[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-1890":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":15,"contributorsCount":15,"subscribersCount":15,"size":15,"stars1d":16,"stars7d":17,"stars30d":18,"stars90d":15,"forks30d":15,"starsTrendScore":19,"compositeScore":20,"rankGlobal":10,"rankLanguage":10,"license":10,"archived":21,"fork":21,"defaultBranch":22,"hasWiki":23,"hasPages":21,"topics":24,"createdAt":10,"pushedAt":10,"updatedAt":29,"readmeContent":30,"aiSummary":31,"trendingCount":15,"starSnapshotCount":15,"syncStatus":32,"lastSyncTime":33,"discoverSource":34},1890,"flowboard","crisng95\u002Fflowboard","crisng95","Flowboard — open-source infinite canvas for AI product videos. Drag nodes for model, product, scene, video — connect them, click Generate. Auto-prompts write themselves. Runs locally; powered by Google Flow + Claude CLI. ","",null,"Python",323,173,3,0,17,28,162,51,6.72,false,"main",true,[25,26,27,28],"ai","claude-cli","google-flow","video","2026-06-12 02:00:34","\u003Cp align=\"center\">\n  \u003Cimg src=\"docs\u002Fassets\u002Flogo-wordmark.svg\" alt=\"Flowboard\" width=\"480\" \u002F>\n\u003C\u002Fp>\n\n\u003Cp align=\"center\">\n  \u003Ca href=\"#license\">\u003Cimg src=\"https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FLicense-MIT-blue.svg\" alt=\"License: MIT\"\u002F>\u003C\u002Fa>\n  \u003Cimg src=\"https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FPython-3.11+-3776AB?logo=python&logoColor=white\" alt=\"Python 3.11+\"\u002F>\n  \u003Cimg src=\"https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FNode-20+-339933?logo=node.js&logoColor=white\" alt=\"Node 20+\"\u002F>\n  \u003Cimg src=\"https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FFastAPI-0.115-009688?logo=fastapi&logoColor=white\" alt=\"FastAPI\"\u002F>\n  \u003Cimg src=\"https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FReact-18-61DAFB?logo=react&logoColor=white\" alt=\"React 18\"\u002F>\n  \u003Cimg src=\"https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FTypeScript-strict-3178C6?logo=typescript&logoColor=white\" alt=\"TypeScript\"\u002F>\n  \u003Cimg src=\"https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FReact%20Flow-12-8A2BE2?logo=react&logoColor=white\" alt=\"React Flow\"\u002F>\n  \u003Cimg src=\"https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FChrome-MV3-4285F4?logo=googlechrome&logoColor=white\" alt=\"Chrome MV3\"\u002F>\n  \u003Cimg src=\"https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FVeo%203.1-i2v-FF6F00?logo=google&logoColor=white\" alt=\"Veo 3.1\"\u002F>\n  \u003Cimg src=\"https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FFlow-Pro%20%2F%20Ultra%20only-EA4335?logo=google&logoColor=white\" alt=\"Flow Pro \u002F Ultra only\"\u002F>\n  \u003Cimg src=\"https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FLLM-Claude%20%C2%B7%20Gemini%20%C2%B7%20Codex-D97757\" alt=\"Claude \u002F Gemini \u002F OpenAI Codex\"\u002F>\n  \u003Cimg src=\"https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FTests-333%20passing-success?logo=pytest&logoColor=white\" alt=\"333 passing\"\u002F>\n  \u003Cimg src=\"https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FStatus-personal%20local--only-orange\" alt=\"Status\"\u002F>\n\u003C\u002Fp>\n\n---\n\n### ☕ Sponsor this project\n\n\u003Ctable align=\"center\">\n  \u003Ctr>\n    \u003Ctd align=\"center\" width=\"50%\">\n      \u003Ca href=\"docs\u002Fassets\u002Fsponsor-qr-vn.jpg\">\n        \u003Cimg src=\"docs\u002Fassets\u002Fsponsor-qr-vn.jpg\" alt=\"Vietnam QR — MoMo \u002F VietQR \u002F napas247\" width=\"240\" \u002F>\n      \u003C\u002Fa>\u003Cbr\u002F>\n      \u003Csub>📱 \u003Cb>Vietnam\u003C\u002Fb>\u003Cbr\u002F>MoMo · VietQR · napas247\u003C\u002Fsub>\n    \u003C\u002Ftd>\n    \u003Ctd align=\"center\" width=\"50%\">\n      \u003Ca href=\"docs\u002Fassets\u002Fsponsor-qr-binance.png\">\n        \u003Cimg src=\"docs\u002Fassets\u002Fsponsor-qr-binance.png\" alt=\"Binance Pay QR — Cris Ng\" width=\"240\" \u002F>\n      \u003C\u002Fa>\u003Cbr\u002F>\n      \u003Csub>💰 \u003Cb>Binance Pay\u003C\u002Fb>\u003Cbr\u002F>Crypto \u002F cross-border\u003C\u002Fsub>\n    \u003C\u002Ftd>\n  \u003C\u002Ftr>\n\u003C\u002Ftable>\n\n\u003Cp align=\"center\">\n  🌍 \u003Cb>International (card):\u003C\u002Fb>\n  \u003Ca href=\"https:\u002F\u002Fko-fi.com\u002Fcrisnguyen95\">\n    \u003Cimg src=\"https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FKo--fi-Buy%20me%20a%20coffee-FF5E5B?logo=kofi&logoColor=white\" alt=\"Ko-fi\" \u002F>\n  \u003C\u002Fa>\n\u003C\u002Fp>\n\n\u003Cp align=\"center\">\n  \u003Csub>\u003Ci>(yes — I moved this up here on purpose. Was afraid nobody scrolls past the badges 😅)\u003C\u002Fi>\u003C\u002Fsub>\n\u003C\u002Fp>\n\n---\n\n\u003Cp align=\"center\">\n  \u003Cb>A local-only, single-user infinite-canvas workspace for AI media workflows.\u003C\u002Fb>\u003Cbr\u002F>\n  Compose characters, products, scenes, and videos as a directed graph. Drive generation through a Chrome extension that proxies requests to Google Flow (Veo 3.1 \u002F GEM_PIX_2).\u003Cbr\u002F>\n  Every node is reusable, every edge is a real data-dependency, every variant is independently regenerable.\n\u003C\u002Fp>\n\n> **⚠ Hard requirements — read this before cloning:**\n>\n> 1. **Google Flow plan: `Pro` or `Ultra` only.** Veo 3.1 i2v + GEM_PIX_2\n>    are gated to paid tiers. The free tier and trial accounts cannot\n>    drive video generation, so Flowboard cannot work on them. Confirm\n>    your plan at [labs.google\u002Ffx](https:\u002F\u002Flabs.google\u002Ffx\u002Ftools\u002Fflow)\n>    before installing.\n> 2. **Chrome extension is mandatory.** All generation requests are\n>    proxied through `extension\u002F` (Chrome MV3) so the agent can ride\n>    your authenticated Flow session + reCAPTCHA token. Without the\n>    extension loaded and connected to `labs.google\u002Ffx\u002Ftools\u002Fflow`, the\n>    `▶ Generate` button does nothing.\n> 3. **One LLM CLI on `PATH` for auto-prompt \u002F vision \u002F planner.**\n>    Flowboard ships a swappable provider layer — pick one in\n>    `Settings → AI Providers`:\n>\n>    - **Claude Code** (default, recommended) —\n>      [`@anthropic-ai\u002Fclaude-code`](https:\u002F\u002Fdocs.claude.com\u002Fclaude-code\u002Finstall) ·\n>      OAuth via your Claude subscription · fully tested in production.\n>    - **Gemini CLI** — [`@google\u002Fgemini-cli`](https:\u002F\u002Fgithub.com\u002Fgoogle-gemini\u002Fgemini-cli) ·\n>      OAuth via Google AI · tested live; ~15 s slower per call than\n>      Claude due to subprocess cold-start.\n>    - **OpenAI Codex** —\n>      [`@openai\u002Fcodex`](https:\u002F\u002Fgithub.com\u002Fopenai\u002Fcodex) · OAuth via\n>      ChatGPT Plus\u002FPro · provider class implemented + auto-detected\n>      but **not yet smoke-tested end-to-end**; treat as beta.\n>\n>    Flowboard does not call any cloud LLM API directly — every\n>    auto-prompt \u002F vision \u002F planner round-trip shells out to the CLI\n>    you've connected, so the cost lives on your existing AI\n>    subscription.\n\n\u003Cp align=\"center\">\n  \u003Ca href=\"#why\">Why\u003C\u002Fa> ·\n  \u003Ca href=\"#showcase\">Showcase\u003C\u002Fa> ·\n  \u003Ca href=\"#how-it-works\">How it works\u003C\u002Fa> ·\n  \u003Ca href=\"#architecture\">Architecture\u003C\u002Fa> ·\n  \u003Ca href=\"#quickstart\">Quickstart\u003C\u002Fa> ·\n  \u003Ca href=\"#features\">Features\u003C\u002Fa>\n\u003C\u002Fp>\n\n---\n\n## Demo\n\n\u003Cp align=\"center\">\n  \u003Ca href=\"docs\u002Fassets\u002Fflowboard-intro.mp4\">\n    \u003Cimg src=\"docs\u002Fassets\u002Fflowboard-intro.gif\" alt=\"Flowboard end-to-end walkthrough\" width=\"720\" \u002F>\n  \u003C\u002Fa>\u003Cbr\u002F>\n  \u003Csub>End-to-end walkthrough — refs → composed image → multi-source i2v. Click for full-quality MP4.\u003C\u002Fsub>\n\u003C\u002Fp>\n\n---\n\n## Why\n\nE-commerce video creative is repetitive: same model, same product, many\nscenes, many short clips. Building it by hand in a generic Veo \u002F Imagen UI\nmeans re-uploading the same character ref every time, re-typing the same\n\"young Korean woman in the cream cropped tee\" prompt every time, and\nlosing track of which 4-variant generation came from which source still.\n\nFlowboard treats the workflow as a graph:\n\n- **Refs are nodes** — upload a character once, upload a product once.\n- **Composed shots are nodes** — `(Character) + (Product) → Image`.\n- **Videos are nodes** — `(Image) → Video` via i2v, with multi-source batch\n  so a 4-variant image spawns 4 videos in one click.\n- **Prompts are auto-synthesised** from upstream context (the configured\n  LLM CLI's vision pass describes each ref → a downstream generator\n  gets the brief spliced into a fashion-editorial prompt). Switch\n  provider in `Settings → AI Providers`; defaults to Claude Code.\n\nThe result: one source-of-truth canvas for an entire campaign.\n\n---\n\n## Showcase\n\nThe graph below is a real export from a board in this project — two ref\nnodes (`#op4v` product, `#0p1u` model) feeding three scene compositions\nand three downstream videos. Every image and clip below was rendered by\nthe pipeline in this repo.\n\n\u003Cp align=\"center\">\n  \u003Cimg src=\"docs\u002Fassets\u002Fcanvas-overview.png\" alt=\"Flowboard canvas — real board export\" width=\"100%\" \u002F>\u003Cbr\u002F>\n  \u003Csub>The actual canvas in the app: 2 refs (left) → studio composition \u003Ccode>#qowj\u003C\u002Fcode> (centre) → scene-variant images (autumn \u002F Seoul \u002F Myeongdong) → 3 video nodes with 4-up i2v variant grids (right).\u003C\u002Fsub>\n\u003C\u002Fp>\n\n```mermaid\ngraph LR\n    A[#op4v Visual asset\u003Cbr\u002F>cream The Famous tee]:::ref\n    B[#0p1u Character\u003Cbr\u002F>Korean female model]:::ref\n    C[#qowj Image\u003Cbr\u002F>studio composition]\n    D[#nkov Image\u003Cbr\u002F>autumn road · 4 variants]\n    E[#l7qd Image\u003Cbr\u002F>Seoul street · 4 variants]\n    F[#xky5 Image\u003Cbr\u002F>Myeongdong dusk · 4 variants]\n    G[#sncj Video\u003Cbr\u002F>studio motion]:::video\n    H[#bwr4 Video\u003Cbr\u002F>autumn motion · 4 variants]:::video\n    I[#uv1p Video\u003Cbr\u002F>Seoul motion · 4 variants]:::video\n\n    A --> C\n    B --> C\n    C --> D\n    C --> E\n    C --> F\n    D --> H\n    E --> I\n    C --> G\n\n    classDef ref fill:#1d4d2e,stroke:#5db97a,color:#fff;\n    classDef video fill:#2b1d4d,stroke:#7c5cff,color:#fff;\n```\n\n### Layer 0 — references (one-time setup)\n\n\u003Ctable>\n\u003Ctr>\n\u003Ctd align=\"center\" width=\"50%\">\n  \u003Cimg src=\"docs\u002Fassets\u002Fvisual-asset-tshirt.webp\" alt=\"Visual asset — t-shirt\" width=\"320\" \u002F>\u003Cbr\u002F>\n  \u003Csub>\u003Cb>#op4v · Visual asset\u003C\u002Fb>\u003Cbr\u002F>Cropped boxy short-sleeve tee in cream ribbed cotton with brown \"The Famous\" centre-chest embroidery.\u003C\u002Fsub>\n\u003C\u002Ftd>\n\u003Ctd align=\"center\" width=\"50%\">\n  \u003Cimg src=\"docs\u002Fassets\u002Fcharacter-model.jpg\" alt=\"Character — Korean female model\" width=\"320\" \u002F>\u003Cbr\u002F>\n  \u003Csub>\u003Cb>#0p1u · Character\u003C\u002Fb>\u003Cbr\u002F>Studio portrait headshot, neutral closed-mouth expression — generated from gender + nationality presets, anchored for downstream identity consistency.\u003C\u002Fsub>\n\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftable>\n\n### Layer 1 — composed studio shot\n\n\u003Cp align=\"center\">\n  \u003Cimg src=\"docs\u002Fassets\u002Fcomposition-base.jpg\" alt=\"Image #qowj — composition\" width=\"640\" \u002F>\u003Cbr\u002F>\n  \u003Csub>\u003Cb>#qowj · Image\u003C\u002Fb> — auto-prompt from upstream briefs: \"Editorial photo, model engaging the camera with direct eye contact, both hands tucked in pockets, knees-up framing, neutral studio backdrop.\" 4 pose-distinct variants generated in one batch.\u003C\u002Fsub>\n\u003C\u002Fp>\n\n### Layer 2 — environment-aware variants\n\nThe synth detects scene context from each new image's brief and switches\nmotion vocabulary (street \u002F studio \u002F café \u002F outdoor). Same character + same\nproduct, three different worlds:\n\n\u003Ctable>\n\u003Ctr>\n\u003Ctd align=\"center\" width=\"33%\">\n  \u003Cimg src=\"docs\u002Fassets\u002Fcomposition-autumn.jpg\" alt=\"Autumn variant\" width=\"280\" \u002F>\u003Cbr\u002F>\n  \u003Csub>\u003Cb>#nkov\u003C\u002Fb> · autumn mountain road, traditional Korean pavilion, red maple foliage\u003C\u002Fsub>\n\u003C\u002Ftd>\n\u003Ctd align=\"center\" width=\"33%\">\n  \u003Cimg src=\"docs\u002Fassets\u002Fcomposition-seoul-street.jpg\" alt=\"Seoul street\" width=\"280\" \u002F>\u003Cbr\u002F>\n  \u003Csub>\u003Cb>#l7qd\u003C\u002Fb> · Seoul street, food stalls, Korean signage\u003C\u002Fsub>\n\u003C\u002Ftd>\n\u003Ctd align=\"center\" width=\"33%\">\n  \u003Cimg src=\"docs\u002Fassets\u002Fcomposition-myeongdong.jpg\" alt=\"Myeongdong dusk\" width=\"280\" \u002F>\u003Cbr\u002F>\n  \u003Csub>\u003Cb>#xky5\u003C\u002Fb> · Myeongdong dusk, red-canopied stalls, Olive Young signage\u003C\u002Fsub>\n\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftable>\n\n### Layer 3 — image-to-video (Veo 3.1 i2v)\n\nCamera is locked-off (e-commerce default — keeps the product fully framed\nthe whole clip); the model performs a **time-coded 2–3 beat editorial\npose-shift** within the 8 seconds. (GitHub renders MP4 inline only when\nhosted on its CDN, so we ship looping GIFs in the README — full-quality\nMP4s live in [`docs\u002Fassets\u002F`](docs\u002Fassets\u002F).)\n\n\u003Ctable>\n\u003Ctr>\n\u003Ctd align=\"center\" width=\"33%\">\n  \u003Cimg src=\"docs\u002Fassets\u002Fvideo-base.gif\" alt=\"Studio motion video\" width=\"280\" \u002F>\u003Cbr\u002F>\n  \u003Csub>\u003Cb>#sncj\u003C\u002Fb> · studio motion · half-step → glance → hair-tuck\u003Cbr\u002F>\u003Ca href=\"docs\u002Fassets\u002Fvideo-base.mp4\">▶ MP4\u003C\u002Fa>\u003C\u002Fsub>\n\u003C\u002Ftd>\n\u003Ctd align=\"center\" width=\"33%\">\n  \u003Cimg src=\"docs\u002Fassets\u002Fvideo-autumn.gif\" alt=\"Autumn motion video\" width=\"280\" \u002F>\u003Cbr\u002F>\n  \u003Csub>\u003Cb>#bwr4\u003C\u002Fb> · autumn road · pivot → pocket → camera smirk\u003Cbr\u002F>\u003Ca href=\"docs\u002Fassets\u002Fvideo-autumn.mp4\">▶ MP4\u003C\u002Fa>\u003C\u002Fsub>\n\u003C\u002Ftd>\n\u003Ctd align=\"center\" width=\"33%\">\n  \u003Cimg src=\"docs\u002Fassets\u002Fvideo-seoul.gif\" alt=\"Seoul motion video\" width=\"280\" \u002F>\u003Cbr\u002F>\n  \u003Csub>\u003Cb>#uv1p\u003C\u002Fb> · Seoul daylight · half-step → over-shoulder glance → hand in pocket\u003Cbr\u002F>\u003Ca href=\"docs\u002Fassets\u002Fvideo-seoul.mp4\">▶ MP4\u003C\u002Fa>\u003C\u002Fsub>\n\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftable>\n\n> All three videos were synthesised from a single click each: the\n> auto-prompt reads the upstream image's `aiBrief`, picks scene-matched\n> motion vocab, and locks the camera to keep the cropped tee in frame for\n> the full clip.\n\n---\n\n## How it works\n\nThe mental model — read this once and the rest of the UI is obvious.\n\n### 1. Refs are nodes you set up once\n\nTwo node types act as **anchors** for the rest of the graph:\n\n| Node | Purpose | How to populate |\n|------|---------|-----------------|\n| **Character** | A person whose identity you want to keep stable across many shots. | Generate from gender + nationality presets (Nam \u002F Nữ × VN \u002F JP \u002F KR \u002F CN \u002F TH \u002F US \u002F FR), or upload your own portrait. The synth hard-anchors it to a frontal, closed-mouth, neutral-expression studio headshot — Veo i2v can't keep identity stable from a smiling-with-teeth source. |\n| **Visual asset** | A product \u002F garment \u002F object that needs to appear in scenes. | Upload (file or URL) or generate from a prompt. Inline `Refine` button uses Flow's `edit_image` to iterate without losing the original. |\n\nEach ref node gets an `aiBrief` automatically (the configured Vision\nprovider describes the image once, persists the description on the\nnode). Downstream auto-prompt walks upstream and pulls these briefs as\ncontext. Toggle off in `Settings → AI Providers` if you'd rather\nsynthesise from typed prompts.\n\n### 2. Composition is just connecting nodes\n\nTo build a composed image, drop an **Image** node and wire upstream refs\ninto it. Click `Generate` (or just press Enter with the prompt empty):\n\n```\n[Character #ujr1]  ───►\n                        \\\n[Visual asset #sqpi] ───► [Image #target]\n                        \u002F\n[Image #other-ref] ───►\n```\n\nAll upstream `mediaId`s are fed to Flow as `IMAGE_INPUT_TYPE_REFERENCE`\ninputs. The auto-prompt synth (`\u002Fapi\u002Fprompt\u002Fauto-batch`) asks the\nconfigured LLM to compose **N pose-distinct prompts** in a single\ncall when you ask for multiple variants — so 4 variants don't all\ncollapse to the same \"hand-on-hip\" stance. The prompt template is fashion-editorial style:\ndirect gaze, neutral closed-mouth, three-quarter angle, hand gesturing\ntoward the garment, knees-up framing.\n\n### 3. Image → Video via Veo i2v\n\nA **Video** node takes a single upstream Image. Connect it, click\n`Generate`, pick:\n\n- **Camera** = `Static` (default, e-commerce-safe — locked-off frame, no\n  zoom or pan, product never crops out) or `Dynamic` (synth picks\n  subtle dolly \u002F pan based on scene).\n- **Source variants** = checkbox per upstream variant + `All \u002F None`\n  bulk action. If the upstream image has 4 variants and you tick all 4,\n  the dispatcher batches **one i2v op per variant** in a single Flow\n  call — 4 source stills → 4 distinct videos.\n\nThe motion synth uses time-coded beats (`0–3s: …`, `3–6s: …`, `6–8s: …`)\nso the model performs an editorial pose-shift sequence inside the 8 s\nclip — never a frozen statue, never an open-mouth smile.\n\n### 4. Auto-prompt is environment-aware\n\nThe synth reads the source still's `aiBrief` and switches motion\nvocabulary based on detected scene:\n\n| Scene type | Motion vocab |\n|------------|-------------|\n| Studio \u002F plain backdrop | hand-on-hip, brush sleeve, head tilt, engage camera |\n| Street \u002F city \u002F sidewalk | half-step forward, hair tuck, glance over shoulder, hand in pocket, smirk |\n| Café \u002F interior | sip from cup, lean back, glance toward window |\n| Beach \u002F nature \u002F outdoor | hair flutter in breeze, slow exhale, look toward horizon |\n\nA studio shot gets editorial poses; a NYC-street shot gets walk-and-glance\nmotion. No code branches — the LLM detects the keyword and picks the\nmatching vocab from the system prompt.\n\n---\n\n## Architecture\n\n```\n┌──────────────────────┐    ┌────────────────────┐    ┌──────────────────────┐\n│  Chrome MV3 ext      │◄───┤  FastAPI agent     ├───►│  SQLite (storage\u002F)   │\n│  - content script    │ WS │  127.0.0.1:8101    │    │  Board, Node, Edge,  │\n│  - injected MAIN     │ ws │  + worker queue    │    │  Request, Asset,     │\n│  - CDN URL allow     │9223│  + WS server :9223 │    │  Plan, ChatMessage,  │\n│  - Captcha bridge    │    │  + LLM CLI bridge  │    │  BoardFlowProject    │\n└──────────────────────┘    └─────────┬──────────┘    └──────────────────────┘\n        ▲                             │\n        │                             ▼\n        │                   ┌────────────────────┐\n        └───── Google Flow  │  React + Vite      │\n              labs.google   │  ReactFlow canvas  │\n              (i2v \u002F image) │  Zustand store     │\n                            │  127.0.0.1:5173    │\n                            └────────────────────┘\n```\n\n- **Frontend** — Vite + React 18 + ReactFlow 12 + Zustand 5 + TypeScript\n  strict. Renders the infinite canvas, dialogs, sidebars. No direct\n  calls to Google Flow.\n- **Agent** — FastAPI + SQLModel + SQLite. Owns the board state, runs\n  an in-process worker queue that proxies all generation requests\n  through the extension, and shells out to the configured LLM CLI\n  (Claude \u002F Gemini \u002F Codex — see *AI Providers* below) for vision +\n  auto-prompt + planner synthesis.\n- **Extension** — Chrome MV3. Lives on `labs.google\u002Ffx\u002Ftools\u002Fflow`,\n  intercepts Flow's API calls (multimodal-fetch in MAIN world for the\n  reCAPTCHA token), proxies them over a localhost WebSocket so the\n  agent never has to touch the browser cookie jar directly.\n- **Storage** — local-only. SQLite for graph + history, a\n  `storage\u002Fmedia\u002F` folder for cached image \u002F video bytes (lazy-fetched\n  from Flow's signed CDN URLs and re-served from the agent so they\n  outlive the 1-hour signed URL TTL).\n\n---\n\n## Quickstart\n\n### Requirements\n\n| Dependency | Why |\n|------------|-----|\n| **Python 3.11** | Agent runtime (FastAPI + SQLModel) |\n| **Node 20+** | Frontend dev server (Vite) |\n| **Chrome \u002F Chromium** | **Mandatory** — hosts the MV3 extension that proxies every Google Flow API call. The agent has zero direct path to Flow without it. |\n| **One LLM CLI** on `PATH` | Vision describe + auto-prompt + planner. Pick one — defaults to **Claude Code** ([`@anthropic-ai\u002Fclaude-code`](https:\u002F\u002Fdocs.claude.com\u002Fclaude-code\u002Finstall)); also supports **Gemini CLI** ([`@google\u002Fgemini-cli`](https:\u002F\u002Fgithub.com\u002Fgoogle-gemini\u002Fgemini-cli)) and **OpenAI Codex** ([`@openai\u002Fcodex`](https:\u002F\u002Fgithub.com\u002Fopenai\u002Fcodex), provider implemented but not yet smoke-tested). All use OAuth against your existing AI subscription — no API key needed. |\n| **Google Flow `Pro` or `Ultra` plan** at [`labs.google\u002Ffx\u002Ftools\u002Fflow`](https:\u002F\u002Flabs.google\u002Ffx\u002Ftools\u002Fflow) | **Free tier and trial accounts will not work.** Veo 3.1 i2v + GEM_PIX_2 image gen are gated to paid plans. |\n\n> **Windows:** Use [WSL2](https:\u002F\u002Flearn.microsoft.com\u002Fen-us\u002Fwindows\u002Fwsl\u002Finstall). All commands assume a Unix shell.\n\n### One-line setup (optional)\n\nIf you have `make` installed, the repo ships shortcut targets that wrap\nSteps 2 + 3:\n\n```bash\nmake install        # agent venv + frontend deps (uses uv if available, else pip)\nmake install-dev    # same, but adds ruff + pytest extras\nmake update         # upgrade agent + frontend deps in place\nmake agent          # run FastAPI on :8101\nmake frontend       # run Vite on :5173\n```\n\n`uv` is auto-detected (~10× faster installs). Install it once with\n`curl -LsSf https:\u002F\u002Fastral.sh\u002Fuv\u002Finstall.sh | sh`, or skip it and the\nMakefile falls back to stdlib `venv` + `pip`. Step 1 (loading the Chrome\nextension) still has to be done manually.\n\n### Step 1 — load the Chrome extension\n\n```bash\ngit clone https:\u002F\u002Fgithub.com\u002F\u003Cyour-fork>\u002Fflowboard.git\ncd flowboard\n```\n\n1. Open `chrome:\u002F\u002Fextensions\u002F` → enable **Developer mode** (top-right).\n2. Click **Load unpacked** → pick the `extension\u002F` folder in this repo.\n3. Open a tab to \u003Chttps:\u002F\u002Flabs.google\u002Ffx\u002Ftools\u002Fflow> and sign in.\n4. The extension's icon should turn coloured once it captures a fresh\n   Flow auth token (~5 s).\n\n### Step 2 — start the agent\n\n```bash\ncd agent\npython3.11 -m venv .venv\n.venv\u002Fbin\u002Fpip install -r requirements.txt\n\n# `--timeout-graceful-shutdown 2` keeps `--reload` snappy when you save\n# a Python file — without it, uvicorn waits forever for the WS to drain.\n.venv\u002Fbin\u002Fuvicorn flowboard.main:app --reload --port 8101 \\\n  --timeout-graceful-shutdown 2\n```\n\nSmoke-test:\n\n```bash\ncurl http:\u002F\u002F127.0.0.1:8101\u002Fapi\u002Fhealth\n# {\"ok\":true,\"extension_connected\":true,\"ws_stats\":{\"connected\":true,\"flow_key_present\":true,...}}\n```\n\n### Step 3 — start the frontend\n\n```bash\ncd frontend\nnpm install\nnpm run dev\n# → http:\u002F\u002Flocalhost:5173\n```\n\nOpen the URL. The first board (\"Untitled\") auto-creates if the DB is\nempty. Add a Character node, generate it, drop a Visual asset, drop an\nImage, wire them up, click **▶ Generate** — the full demo above is\nabout 15 minutes of clicking.\n\n### Run tests\n\n```bash\n# Agent\ncd agent && .venv\u002Fbin\u002Fpython -m pytest -q\n# 333 passed\n\n# Frontend\ncd frontend && npx tsc -p . --noEmit && npx vite build\n```\n\n---\n\n## Features\n\n### Ref-style nodes\n\n- **Character** — generate via gender + nationality preset chips, or\n  upload your own headshot. Hard-anchored to a frontal, closed-mouth,\n  neutral-expression portrait so Veo i2v keeps identity stable across\n  every downstream clip.\n- **Visual asset** — upload (file \u002F URL) or generate. Refine in-place\n  with a different prompt (Flow `edit_image`, BASE_IMAGE preserved,\n  optional reference list).\n\n### Composition nodes\n\n- **Image** — multi-ref aware. Connect any number of upstream\n  characters, visual assets, or other images; all of them flow in as\n  Flow's `IMAGE_INPUT_TYPE_REFERENCE` inputs.\n  - 1–4 variants per gen, each with its own pose-distinct prompt\n    (the LLM rotates through an 8-stance pool per variant — never two\n    \"hand-on-hip\" variants in the same gen).\n  - Default aspect ratio inherits from upstream node; mismatched\n    upstream aspects fall back to 9:16.\n- **Storyboard** — sequenced 1–8 narrative shots in one node. The\n  planner LLM emits per-beat prompts AND a continuity tree: each beat\n  declares whether it's a fresh root (`gen_image`) or continues from\n  an earlier beat (`edit_image` from that beat's mediaId). Roots\n  dispatch in parallel batches of 4; continuations BFS through the\n  tree, siblings parallel. Refs from upstream edges apply to every\n  shot. Failed shots stay `partial` and can be retried per-tile —\n  blocked descendants surface a 🔒 until their parent is retried.\n  Useful for unbox → try-on → going-out arcs, scene chains, and\n  e-commerce shot lists.\n- **Video** — image-to-video via Veo. **Multi-source i2v**: a 4-variant\n  upstream image dispatches a single batch with one item per variant →\n  one video per source. Or pick a subset (toggleable thumbnails +\n  All \u002F None bulk action).\n  - Camera = `Static` (locked-off, e-commerce default) or `Dynamic`\n    (synth picks dolly \u002F pan \u002F micro-shift to fit the scene).\n  - Motion synth uses time-coded beats so the model performs an\n    editorial 2–3 pose-shift sequence inside the 8s clip — never a\n    frozen statue.\n\n### Auto-prompt synthesis\n\n- Vision describes each new asset (configured CLI's multimodal\n  attachment path — `@\u003Cpath>` for Claude \u002F Gemini, `--image` for Codex\n  when available) → saved as `aiBrief` on the node.\n- Downstream gen with empty prompt → `\u002Fapi\u002Fprompt\u002Fauto` walks upstream\n  edges, gathers briefs, asks the configured LLM to compose a prompt\n  that matches the scene + showcases the product.\n- For multi-variant gens, `\u002Fapi\u002Fprompt\u002Fauto-batch` returns N\n  pose-distinct prompts in a single LLM call.\n- **Vision toggle** in `Settings → AI Providers`: when OFF, the\n  synthesiser falls back to each upstream node's typed `prompt`\n  instead of a vision-derived brief. Manual upload paths still run\n  vision automatically (the user explicitly added bytes) — only the\n  gen-completion auto-brief is gated.\n\n### AI Providers (multi-LLM)\n\nA **🤖 Provider** chip in the top-right toolbar opens a dialog where\nyou switch which LLM powers Flowboard. One provider serves all three\nfeatures (Auto-Prompt \u002F Vision \u002F Planner) — switching is one decision,\nnot three. Per-feature test buttons run a small ping per feature and\ngate the **Apply changes** button until all three pass green, so you\nnever apply a switch that's silently broken.\n\n| Provider | Auth | Status |\n|---|---|---|\n| **Claude Code** | OAuth via `claude` CLI · Anthropic browser sign-in | ✅ Default · production-tested |\n| **Gemini CLI** | OAuth via `gemini` CLI · Google AI Ultra plan | ✅ Tested · ~15 s slower than Claude |\n| **OpenAI Codex** | OAuth via `codex` CLI · ChatGPT Plus\u002FPro | ⚠ Provider implemented but not yet smoke-tested |\n\nBackend keeps a Grok REST provider class for power users who edit\n`~\u002F.flowboard\u002Fsecrets.json` directly, but the UI doesn't surface it\nbecause xAI hasn't shipped an end-user CLI.\n\n### Activity feed\n\nA **🔔 bell** sits in the toolbar next to the AI Provider chip. Click\nit to see every backend operation in DESC order: gen image \u002F gen\nvideo \u002F edit image \u002F auto-prompt \u002F vision \u002F planner — each with its\nstatus pill (✓ done · ⟳ running · ✗ failed) and how long it ran. Click\na row to open a detail modal with the full input params, output\nresult, and error JSON (with copy buttons), so you can diagnose a\nfailed gen without tailing agent logs.\n\nThe bell badge counts running + recently-failed-unread items, with a\nred tint when any failure is unread. Polling is 5 s while the dropdown\nis open, 30 s while closed, and pauses when the tab is backgrounded.\n\n### Workflow ergonomics\n\n- **Drop-add popover** — drag an edge into empty canvas, popover at the\n  drop point with `Image` \u002F `Video` quick-add → new node + auto-wired\n  edge.\n- **Easy edge editing** — click an edge to select (accent ring + glow),\n  Backspace \u002F Delete to remove. 24 px transparent hit-slop so edges are\n  forgiving to grab.\n- **Clone variant** — `New variant +` in the result viewer creates a\n  sibling node with identical upstream connections, prefills the\n  prompt, opens the gen dialog.\n- **Project sidebar** — multiple boards on the same agent, each with\n  its own Flow project mapping. Rename \u002F delete with cascade (clears\n  all child rows: nodes, edges, requests, assets, plans, runs).\n\n---\n\n## Repo layout\n\n```\nagent\u002F                  FastAPI service (Python 3.11)\n  flowboard\u002F\n    routes\u002F             HTTP endpoints (boards, nodes, edges, requests,\n                        upload, vision, prompt, plans, llm, activity, …)\n    services\u002F           Flow SDK, prompt synth, vision describe,\n                        pipeline executor, activity logger\n      llm\u002F              Multi-LLM provider layer (registry, secrets,\n                        Claude \u002F Gemini \u002F OpenAI Codex \u002F Grok)\n      claude_cli.py     Subprocess detail behind ClaudeProvider\n    worker\u002F             In-process queue (gen_image, gen_video,\n                        edit_image, upload_image)\n    db\u002F                 SQLModel definitions\n  tests\u002F                333+ pytest tests\n\nfrontend\u002F               Vite + React + ReactFlow\n  src\u002F\n    canvas\u002F             Board.tsx, NodeCard.tsx, AddNodePalette.tsx\n    components\u002F\n      activity\u002F         ActivityBell + dropdown + detail modal\n      settings\u002F         AiProvidersSection + ProviderCard + setup modal\n      AiProviderBadge.tsx · AiProviderDialog.tsx · GenerationDialog · ResultViewer · ProjectSidebar · ChatSidebar · Toolbar · Toaster\n    store\u002F              Zustand: board, generation, pipeline, settings\n    api\u002F                client.ts, autoBrief.ts\n\nextension\u002F              Chrome MV3 (content script + injected MAIN)\ndocs\u002F                   Static assets (this README, screenshots, demo media)\nstorage\u002F                Local cache + SQLite (gitignored)\n```\n\n---\n\n## Status\n\nPersonal local-only tool. **333 \u002F 333 tests passing** (agent), tsc\nclean (frontend). Caveats:\n\n- ⚠ **Google Flow plan must be `Pro` or `Ultra`.** Free tier and trial\n  accounts have no access to Veo 3.1 i2v \u002F GEM_PIX_2 — every generation\n  call will fail.\n- ⚠ **Chrome extension must be loaded and connected.** The agent does\n  not talk to Flow directly — all i2v \u002F image \u002F edit requests are\n  proxied through `extension\u002F` over a localhost WebSocket. No\n  extension → no generation.\n- ⚠ HMAC-secured WS (`X-Callback-Secret` per agent boot) — single\n  loopback only, not multi-user.\n- ⚠ Google Flow rate limits still apply within your paid tier.\n- ⚠ Veo \u002F Imagen content filters\n  (`PUBLIC_ERROR_PROMINENT_PEOPLE_FILTER_FAILED`,\n  `PUBLIC_ERROR_AUDIO_FILTERED`) — surfaced verbatim in the activity\n  feed + failed-request error so the user can diagnose \u002F iterate.\n- ⚠ Auto-prompt + vision + planner require **one** LLM CLI on `PATH`\n  (Claude Code recommended; Gemini CLI tested; OpenAI Codex provider\n  implemented but not yet smoke-tested). Without any CLI, the\n  `Generate` button still works if you type your own prompt — only\n  the auto-prompt-from-empty path is unavailable.\n\n## Related\n\n- [`crisng95\u002Fflowkit`](https:\u002F\u002Fgithub.com\u002Fcrisng95\u002Fflowkit) — the same\n  Chrome-extension-bridge approach to Google Flow, but for **YouTube\n  story videos** (multi-scene, narration, thumbnails). Flowboard\n  borrows the bridge architecture.\n\n## License\n\nMIT (proposed — license file pending).\n\n---\n\n## Credits\n\nGenerated media in this README was produced through the pipeline using\n[Google Flow](https:\u002F\u002Flabs.google\u002Fflow). Auto-prompt + vision synthesis\ndefaults to [Claude](https:\u002F\u002Fclaude.ai) via the local CLI; multi-LLM\nsupport adds Google's [Gemini CLI](https:\u002F\u002Fgithub.com\u002Fgoogle-gemini\u002Fgemini-cli)\nand OpenAI's [Codex CLI](https:\u002F\u002Fgithub.com\u002Fopenai\u002Fcodex) as alternative\nproviders — pick one in `Settings → AI Providers`.\n\n---\n\n## Community & Support\n\n\u003Cp align=\"center\">\n  \u003Ca href=\"https:\u002F\u002Fwww.facebook.com\u002Fgroups\u002Fflowkit.flowboard.community\">\n    \u003Cimg src=\"https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FJoin%20the%20Community-FlowKit%20%26%20Flowboard%20on%20Facebook-1877F2?style=for-the-badge&logo=facebook&logoColor=white\" alt=\"Join the FlowKit & Flowboard Facebook Group\" \u002F>\n  \u003C\u002Fa>\n\u003C\u002Fp>\n\nThe shared community for both **FlowKit** and **Flowboard**. Drop in to:\n\n- Post the shots and clips you've generated\n- Share node-graph patterns, vibe presets, and prompt recipes that work for you\n- Ask for help when an output isn't matching what you imagined\n- Request features and report bugs you've hit in the wild\n- Trade tips on Google Flow plan limits, Veo i2v behaviour, and LLM CLI setup (Claude \u002F Gemini \u002F Codex)\n\n→ **[facebook.com\u002Fgroups\u002Fflowkit.flowboard.community](https:\u002F\u002Fwww.facebook.com\u002Fgroups\u002Fflowkit.flowboard.community)**\n","Flowboard 是一个用于生成AI产品视频的开源无限画布工具。用户可以通过拖拽节点来设置模型、产品、场景和视频，并通过连接这些节点自动生成视频，自动提示功能使得创作过程更加流畅。该项目使用Python编写，前端采用React和TypeScript构建，后端则利用FastAPI进行开发，支持在本地运行，并且集成了Google Flow与Claude CLI等先进的人工智能技术以增强其功能。适合需要快速创建高质量AI驱动的产品演示视频或创意内容制作的个人开发者及小型团队使用。",2,"2026-06-11 02:46:39","CREATED_QUERY"]