Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- **flow.google.com: `image i2i --ref <uuid>` references an earlier image of the same
project in place** ([#995](https://github.com/ffroliva/gflow-cli/issues/995)). When the
local catalog records the image in the `--project` being generated in (and kept its Flow
caption), the ref is marked `in_project` and goes through the existing #913 picker path:
no upload, so a t2i → review → i2i pipeline split across invocations no longer needs
Flow's upload-terms confirmation. MCP image tasks behave the same (`ref_meta` now carries
the catalog's `flow_project_id`). Refs from another project, or without a recorded
caption, still exit 36.

- `scripts/dev/cleanup.py` — sweeps what a release or takeover session leaves behind:
merged worktrees and branches, done `pr-<N>` fetch branches, merged same-repo origin
branches (`--remote`), stray `.env` copies, old `bt*` pytest basetemps, and dead agentctl
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ gflow CLI → Provider (interchangeable) → Flow (ui_automation) / Mock (te

**Current transport:** `ui_automation` drives Flow through a persistent Playwright Chromium profile. It is production-stable and verified end-to-end every release (see the per-release `LIVE_VERIFICATION_*` evidence files).

**Two Flow frontends:** Google is moving accounts from `labs.google` onto `flow.google.com` ([#639](https://github.com/ffroliva/gflow-cli/issues/639)) — same product, different widget toolkit and wire protocol (`batchexecute` instead of `aisandbox-pa`). The migrated driver covers text-to-video, image-to-video from a local start frame, reference-to-video from local files, text-to-image, image-to-image from local files, and a single-segment `video extend`. Image generation supports Nano Banana 2.1 (`nano2`, [#958](https://github.com/ffroliva/gflow-cli/issues/958)) / 2 Lite / Pro, the five aspect ratios measured on that host (16:9, 4:3, 1:1, 3:4, 9:16), and counts 1–4; an existing project is required at the transport boundary. Images can tag a character by `@Name` ([#723](https://github.com/ffroliva/gflow-cli/issues/723)). An account served the **agent-only** composer ([#799](https://github.com/ffroliva/gflow-cli/issues/799)) gets text-to-image and text-to-video only. UUID media references, an entity id without a name, instructions, Imagen 4, and the rest of the matrix keep the labs driver until ported (`GFLOW_CLI_FLOW_HOST`, see [CONFIGURATION](docs/CONFIGURATION.md#gflow_cli_flow_host)).
**Two Flow frontends:** Google is moving accounts from `labs.google` onto `flow.google.com` ([#639](https://github.com/ffroliva/gflow-cli/issues/639)) — same product, different widget toolkit and wire protocol (`batchexecute` instead of `aisandbox-pa`). The migrated driver covers text-to-video, image-to-video from a local start frame, reference-to-video from local files, text-to-image, image-to-image from local files, and a single-segment `video extend`. Image generation supports Nano Banana 2.1 (`nano2`, [#958](https://github.com/ffroliva/gflow-cli/issues/958)) / 2 Lite / Pro, the five aspect ratios measured on that host (16:9, 4:3, 1:1, 3:4, 9:16), and counts 1–4; an existing project is required at the transport boundary. Images can tag a character by `@Name` ([#723](https://github.com/ffroliva/gflow-cli/issues/723)). An account served the **agent-only** composer ([#799](https://github.com/ffroliva/gflow-cli/issues/799)) gets text-to-image and text-to-video only. An image `--ref <uuid>` is referenced in place when the catalog records it in the same `--project` ([#995](https://github.com/ffroliva/gflow-cli/issues/995)). Other UUID media references, an entity id without a name, instructions, Imagen 4, and the rest of the matrix keep the labs driver until ported (`GFLOW_CLI_FLOW_HOST`, see [CONFIGURATION](docs/CONFIGURATION.md#gflow_cli_flow_host)).

**What's blocked:** a pure HTTP transport for video generation. The video upload endpoint returns HTTP 401 under non-Chrome browsers plus a reCAPTCHA mint we cannot reproduce headlessly. Three earlier HTTP strategies (`evaluate_fetch`, `bearer`, `sapisidhash`) live under `src/gflow_cli/api/transports/experimental/` for research, off the production path.

Expand Down
2 changes: 1 addition & 1 deletion docs/CONFIGURATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,7 @@ Measurement script: `scripts/dev/spike_offscreen_window.py`.
- `flow.google.com` — force the migrated composer for everything, including what it cannot serve yet (those requests then exit 36/11 instead of falling back).
- `labs.google` — never use the migrated composer; where Flow serves `flow.google.com`, requests fail with exit 36 (kill switch).
**Default:** `auto`
**Scope today:** the migrated composer covers `gflow video t2v`, local-file `video i2v` / `r2v`, `gflow image t2i`, and local-file `gflow image i2i`. Images support Nano Banana 2.1 (`nano2`, #958) / 2 Lite / Pro, all five aspect ratios (16:9, 4:3, 1:1, 3:4, 9:16 — `3:4` was added to that host's radiogroup by 2026-09-17, #864) and count 1–4; the page owns the `ogiZ0b` reCAPTCHA + submit and the response already contains completed signed image URLs. Local-file start+end frames (`--initial-frame` + `--end-frame`) are ported (#639). Image prompts may tag a character with `@Name` (or `--reference-entity` paired with `--reference-entity-name`; an id alone exits 36), attached through the composer's `@` picker (#723). `video extend` is ported for a single segment from a clip (one PROMPT; `-n` > 1, `--scene`/`--resume-from`, `--seed` and an `--aspect` other than the source's exit 36, and `-o` saves the new extension clip only, #882). Frames given by UUID/`@Name`, media references by UUID/`@Name`, character entities on video, Agent instructions, Imagen 4, scenes, instructions and tools are not ported yet and fail before submit where Flow serves flow.google.com. MCP uses the same image service and queue payload, and inherits this setting from the server/daemon environment rather than per call.
**Scope today:** the migrated composer covers `gflow video t2v`, local-file `video i2v` / `r2v`, `gflow image t2i`, and local-file `gflow image i2i`. Images support Nano Banana 2.1 (`nano2`, #958) / 2 Lite / Pro, all five aspect ratios (16:9, 4:3, 1:1, 3:4, 9:16 — `3:4` was added to that host's radiogroup by 2026-09-17, #864) and count 1–4; the page owns the `ogiZ0b` reCAPTCHA + submit and the response already contains completed signed image URLs. Local-file start+end frames (`--initial-frame` + `--end-frame`) are ported (#639). Image prompts may tag a character with `@Name` (or `--reference-entity` paired with `--reference-entity-name`; an id alone exits 36), attached through the composer's `@` picker (#723). `video extend` is ported for a single segment from a clip (one PROMPT; `-n` > 1, `--scene`/`--resume-from`, `--seed` and an `--aspect` other than the source's exit 36, and `-o` saves the new extension clip only, #882). Frames given by UUID/`@Name`, media references by UUID/`@Name` (except an image `--ref <uuid>` the catalog records in the same `--project`, #995), character entities on video, Agent instructions, Imagen 4, scenes, instructions and tools are not ported yet and fail before submit where Flow serves flow.google.com. MCP uses the same image service and queue payload, and inherits this setting from the server/daemon environment rather than per call.

### `GFLOW_CLI_AGENT_CONFIRM`

Expand Down
8 changes: 8 additions & 0 deletions docs/REFERENCE_STRATEGIES.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,14 @@ unchanged:** video characters are still refused there: `--reference-entity` exit
carries media at one slot and characters at another. It must hold exactly the
requested local references plus the committed character: one missing or one extra
aborts the submit before Flow generates anything.
- **An earlier image of the same project rides in place too ([#995](https://github.com/ffroliva/gflow-cli/issues/995)).**
`--ref <uuid>` (and an MCP image task's `refs`) is referenced through the same picker
path as `batch:N`, with no upload, when the local catalog records that image in the
`--project` being generated in and kept its Flow caption (the default
`GFLOW_CLI_HISTORY_PROMPTS=store`). The catalog only routes it: the tile must still be in
the page's project grid, so a stale row fails with exit 32 instead of attaching something
else. A UUID from another project, or one without a recorded caption, still exits 36.
Because nothing is uploaded, this path never meets Flow's one-time upload-terms dialog.
- **What to do on a refusal.**
- **Exit 32:** no option, or several, carry the exact name. Rename the colliding asset in
Flow, or give the character a unique one-word name.
Expand Down
7 changes: 5 additions & 2 deletions docs/USAGE.md
Original file line number Diff line number Diff line change
Expand Up @@ -732,7 +732,10 @@ Options:
> `--reference-entity`), are not ported to the migrated composer yet. `image t2i` and local-file `image i2i` also run on a moved
> account, and on images a character can be tagged with `@Name` or `--reference-entity`
> (see [REFERENCE_STRATEGIES § flow.google.com](REFERENCE_STRATEGIES.md#on-flowgooglecom-images-only-723);
> video is unchanged); UUID/instruction/Imagen-4 image forms still exit 36. `flow.google.com` forces the migrated composer,
> video is unchanged). An image `--ref <uuid>` is referenced in place, with no upload, when the
> local catalog records that image in the same `--project` and keeps its Flow caption
> ([#995](https://github.com/ffroliva/gflow-cli/issues/995)); any other UUID, and instruction/Imagen-4
> image forms, still exit 36. `flow.google.com` forces the migrated composer,
> `labs.google` switches it off — see [CONFIGURATION § GFLOW_CLI_FLOW_HOST](CONFIGURATION.md#gflow_cli_flow_host).

```bash
Expand Down Expand Up @@ -2125,7 +2128,7 @@ shell scripts can branch on the failure mode without parsing stderr.
| `33` | — (`gflow doctor` verdict) | Doctor found warn/fail findings — a successful diagnosis, not an error class | Review the report; see [`gflow doctor`](#gflow-doctor) |
| `34` | `SyncPartialError` | `gflow data sync` failed on some projects but succeeded on others — completed writes stay committed | Retryable: re-run the same command; it resumes with what is still nameless (see [`gflow data sync`](#gflow-data-sync)) |
| `35` | `ExtendUnavailableError` | No Veo extend model is orderable for this account and aspect — the extend family is tier-gated and there is no square variant. **Never auto-retry**: a tier gate does not clear on its own. |
| `36` | `FlowHostMigratedError` | Flow served the project from `flow.google.com` and the request could not be represented by the migrated composer, or `GFLOW_CLI_FLOW_HOST=labs.google` disabled it. Supported today: `video t2v`; local-file video i2v/r2v; `image t2i`; local-file `image i2i`; and `gflow run --config` rows referencing an earlier row (`batch:N`) or a local file; `image upscale`; `video upscale` (served here only); and single-segment `video extend`. Images may tag a character by name (`@Name`, or `--reference-entity` with `--reference-entity-name`, #723); image UUID references, an entity id without a name, instructions, Imagen 4 and `image batch` remain unsupported. On an agent-only composer ([#799](https://github.com/ffroliva/gflow-cli/issues/799)), generation is limited to `image t2i` and `video t2v` (one 9:16 or 16:9 clip). Not selector drift (23) | **Not retryable.** Use one of the supported forms, or the REST surface (`gflow project list`, `gflow data …`); follow #639 for the remaining matrix |
| `36` | `FlowHostMigratedError` | Flow served the project from `flow.google.com` and the request could not be represented by the migrated composer, or `GFLOW_CLI_FLOW_HOST=labs.google` disabled it. Supported today: `video t2v`; local-file video i2v/r2v; `image t2i`; local-file `image i2i`; and `gflow run --config` rows referencing an earlier row (`batch:N`) or a local file; `image i2i --ref <uuid>` of an image the catalog records in the same `--project` (#995); `image upscale`; `video upscale` (served here only); and single-segment `video extend`. Images may tag a character by name (`@Name`, or `--reference-entity` with `--reference-entity-name`, #723); other image UUID references, an entity id without a name, instructions, Imagen 4 and `image batch` remain unsupported. On an agent-only composer ([#799](https://github.com/ffroliva/gflow-cli/issues/799)), generation is limited to `image t2i` and `video t2v` (one 9:16 or 16:9 clip). Not selector drift (23) | **Not retryable.** Use one of the supported forms, or the REST surface (`gflow project list`, `gflow data …`); follow #639 for the remaining matrix |
| `37` | `InsufficientCreditsError` | The account's balance is short **for the model it asked for**, so Flow **replaced** the submit control with its `Insufficient credits warning` instead of disabling it. Short, not necessarily empty: measured 2026-09-07, an account holding **50** credits requesting `--model veo-quality` (**100**) rendered the warning. Explicitly **not** selector drift (23): reporting it as drift told users to file a frontend bug over a credit shortfall | Check the balance with `gflow credits user`, then pick a cheaper `--model` (`veo-lite` costs 10), top up, or wait for the allowance to reset. Nothing was submitted, so no credit was spent. `gflow image` draws on a separate daily quota and may still work |
| `38` | `FlowAccountChooserError` | The post-migration hop landed on Google's account chooser and the profile's recorded account (`.gflow_account`) could not be selected automatically (row absent, click-through did not return to the editor, or `--account` mismatch) | **Not retryable**: run `gflow auth login --profile <name>` and complete the chooser manually, while signed in as the recorded account (re-run `gflow auth login` if the chooser offers a different session) |
| `39` | `FlowAccessUnavailableError` | Flow loaded and routed to its own "you don't have access" screen (`<flow-pinhole-unavailable-screen>`): this Google account has no Flow entitlement. Detected by component, not by URL — the hop is client-side (`flow.google.com/` answers 200) and the path varies (`/unavailable`, `/u/8/unavailable`). Explicitly **not** auth expiry (3/8) and **not** selector drift (23): nothing expired and nothing drifted | **Not retryable, and signing in again cannot change it.** Flow needs an age-verified account in a supported region on a Google AI Plus/Pro/Ultra or qualifying Workspace plan — check which applies at [Google's eligibility page](https://support.google.com/flow/answer/16353333) and open https://flow.google.com in a browser on this account to confirm |
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Plan: catalogued refs of the target project referenced in place (#995)

- [x] Red: CLI `_enrich_uuid_refs` project-scope tests (scenarios 1, 3–6).
- [x] Red: MCP `_resolve_payload_refs` records `flow_project_id` in `ref_meta` (scenario 2).
- [x] Red: worker `build_image_request` sets `in_project` from `ref_meta` + `project_id` (scenario 2–5).
- [x] Red: CLI passes the resolved project to the enrichment (`--project` → `project_id`).
- [x] Green: `api.image.recorded_in_project`; wire it into `cli_image._enrich_uuid_refs`, `mcp.tools._ref_meta_entry`, `worker.codec.build_image_request`.
- [x] Docs: REFERENCE_STRATEGIES (flow.google.com section), USAGE (i2i on the migrated host), KNOWN_ISSUES (#639 entry), CHANGELOG.
- [x] Gates: ruff check + format check, pyright, pytest with coverage, CLI↔MCP parity tests, repo hygiene / doc links / website docs checks.
- [ ] Live: one `image i2i --ref <uuid-from-earlier-t2i> --project P` on a flow.google.com account (no credits). Not run by the author.
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Predict: reference a catalogued image of the target project in place on flow.google.com (#995)

**Proposal.** `ImageRef.in_project` is today set only for images produced in the current
process (#913). Also set it when the local catalog records the `--ref <uuid>` image in the
**same Flow project** the generation targets, on the CLI (`_enrich_uuid_refs`) and the
MCP/worker path (`ref_meta.flow_project_id` → `worker.codec.build_image_request`). No
transport change: the migrated composer's existing in-place path (`reference_existing`)
does the work.

## Verdict: GO (with the evidence caveat below)
**Confidence:** 7/10.

## Persona signals

| Persona | Signal | Key point |
|---|---|---|
| Architect | GO | One predicate (`api.image.recorded_in_project`) shared by both surfaces; no new transport branch, no new selector. The routing decision stays at the request boundary, where #913 put it. |
| Security / account safety | GO | Nothing new reaches Flow: the same `@` picker search, the same `/asb/<token>` identity match against `img[data-media-id]`, the same `_image_body_problem` submit check. The catalog is only a routing hint; a stale or wrong catalog row still fails loud (`ReferenceNotFoundError`) instead of attaching the wrong image. Removes an upload, so it also avoids the account-level upload-terms dialog (exit 27) for a pure t2i → i2i flow. |
| Performance | GO | Saves an upload per reused reference. The grid may not list a just-generated tile until a reload; `reference_existing` already reloads within `EXISTING_REF_WAIT_S`. |
| CLI / MCP UX | GO | Same behaviour on both surfaces (CLI↔MCP mirror). Refusals unchanged for refs without a recorded caption (`history_prompts=redacted`) or from another project: exit 36 as today. Docs: REFERENCE_STRATEGIES, USAGE, KNOWN_ISSUES, CHANGELOG. |
| Devil's Advocate | CAUTION | The in-place path has only been exercised live for images of the **current** run (#913). An image from an earlier run should be identical to Flow (same project grid, same picker), but that is an inference until one live i2i proves it. |

## Required before merge
1. A maintainer-run (or contributor-run) live `image i2i --ref <uuid> --project P` on flow.google.com where `<uuid>` came from an earlier `image t2i --project P`: expect `migrated.existing_references_attached` and no upload. Images spend no credits. **Not run by the author** (see the PR's verification section).
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Scenario: catalogued refs of the target project on flow.google.com (#995)

| # | Given | When | Then |
|---|---|---|---|
| 1 | Catalog row for `U`: image, `flow_project_id=P`, caption recorded | `image i2i --ref U --project P` (CLI) | `ImageRef(U).in_project=True`; migrated host references it in place (no upload) |
| 2 | Same, via MCP `generate_image` task with `project_id=P` | worker builds the request | `ref_meta[U].flow_project_id == P` → `in_project=True` (CLI↔MCP mirror) |
| 3 | Catalog row records `flow_project_id=Q` | `--project P` | `in_project=False` → exit 36 as today |
| 4 | No `--project` (scratch project) | i2i | `in_project=False` (a new project cannot hold `U`) |
| 5 | Catalog row has no project | `--project P` | `in_project=False` |
| 6 | Catalog row is a video | `--project P` | ref untouched (existing guard) |
| 7 | Catalog row in `P` but no caption (`GFLOW_CLI_HISTORY_PROMPTS=redacted`) | i2i | `in_project=True`, but the migrated composer refuses "an image Flow returned without a caption" (exit 36, unchanged) |
| 8 | Catalog says `P`, but the tile is gone from Flow (deleted) | i2i | `await_existing_references` misses after its reload window → `ReferenceNotFoundError`, nothing generated (unchanged) |
| 9 | Unknown UUID / catalog unavailable | i2i | ref untouched → exit 36 on flow.google.com (unchanged) |
| 10 | labs.google account | i2i with a catalogued ref | no behaviour change: the labs path never reads `in_project` |
Loading
Loading