gflow-cli 0.30.0__tar.gz → 0.32.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (525) hide show
  1. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/AGENTS.md +1 -1
  2. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/CHANGELOG.md +24 -1
  3. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/KNOWN_ISSUES.md +159 -0
  4. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/PKG-INFO +1 -1
  5. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/docs/INDEX.md +1 -1
  6. gflow_cli-0.32.0/docs/LIVE_VERIFICATION_v0.31.0.md +83 -0
  7. gflow_cli-0.32.0/docs/LIVE_VERIFICATION_v0.32.0.md +74 -0
  8. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/docs/MCP.md +1 -1
  9. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/docs/USAGE.md +24 -9
  10. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/pyproject.toml +1 -1
  11. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/scripts/dev/spike_movie_attach_payload.py +1 -1
  12. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/skills/gflow-cli/SKILL.md +2 -2
  13. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/__init__.py +1 -1
  14. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/api/transports/drivers/agentic.py +61 -8
  15. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/api/transports/drivers/classic.py +1 -1
  16. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/api/transports/ui_automation_video.py +140 -16
  17. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/api/video.py +44 -2
  18. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/cli_image.py +20 -2
  19. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/cli_video.py +55 -25
  20. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/data/recorder.py +129 -0
  21. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/errors.py +59 -0
  22. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/image_batch.py +100 -22
  23. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/worker/daemon.py +42 -16
  24. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/api/test_video.py +47 -0
  25. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/api/transports/drivers/test_agentic.py +119 -4
  26. gflow_cli-0.32.0/tests/api/transports/drivers/test_classic.py +68 -0
  27. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/api/transports/test_ui_automation_video.py +435 -3
  28. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/cli/test_cli_image.py +177 -0
  29. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/cli/test_cli_video.py +73 -0
  30. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/data/test_recorder.py +237 -0
  31. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/features/test_video_agent_ui_steps.py +3 -2
  32. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/image_batch/test_image_manifest.py +325 -0
  33. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/image_batch/test_observability_events.py +26 -0
  34. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/test_errors.py +36 -0
  35. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/worker/test_daemon.py +183 -1
  36. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/uv.lock +1 -1
  37. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/.claude/README.md +0 -0
  38. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/.claude/commands/gflow/active.md +0 -0
  39. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/.claude/commands/gflow/branch-review.md +0 -0
  40. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/.claude/commands/gflow/changelog.md +0 -0
  41. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/.claude/commands/gflow/check.md +0 -0
  42. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/.claude/commands/gflow/doc-review.md +0 -0
  43. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/.claude/commands/gflow/issue-assessment.md +0 -0
  44. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/.claude/commands/gflow/issue-resolve.md +0 -0
  45. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/.claude/commands/gflow/known-issues.md +0 -0
  46. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/.claude/commands/gflow/next.md +0 -0
  47. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/.claude/commands/gflow/plan.md +0 -0
  48. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/.claude/commands/gflow/pr-council-review.md +0 -0
  49. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/.claude/commands/gflow/predict.md +0 -0
  50. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/.claude/commands/gflow/release.md +0 -0
  51. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/.claude/commands/gflow/scenario.md +0 -0
  52. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/.claude/commands/gflow/sonar.md +0 -0
  53. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/.claude/commands/gflow/status.md +0 -0
  54. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/.env.template +0 -0
  55. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/.gitattributes +0 -0
  56. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/.github/CODEOWNERS +0 -0
  57. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  58. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/.github/copilot-instructions.md +0 -0
  59. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/.github/dependabot.yml +0 -0
  60. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/.github/workflows/ci.yml +0 -0
  61. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/.github/workflows/external-pr-triage.yml +0 -0
  62. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/.github/workflows/governance-advisory.yml +0 -0
  63. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/.github/workflows/governance-benchmark.yml +0 -0
  64. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/.github/workflows/main-base-guard.yml +0 -0
  65. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/.github/workflows/release.yml +0 -0
  66. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/.gitignore +0 -0
  67. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/.gitleaks.toml +0 -0
  68. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/.pre-commit-config.yaml +0 -0
  69. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/.secrets.baseline +0 -0
  70. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/CLAUDE.md +0 -0
  71. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/CONFIGURATION.md +0 -0
  72. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/CONTRIBUTING.md +0 -0
  73. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/DISCLAIMER.md +0 -0
  74. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/GEMINI.md +0 -0
  75. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/LICENSE +0 -0
  76. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/PLAN.md +0 -0
  77. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/README.md +0 -0
  78. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/RELEASE.md +0 -0
  79. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/ROADMAP.md +0 -0
  80. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/conftest.py +0 -0
  81. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/docker-compose.yml +0 -0
  82. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/docs/AGENT_GUIDE.md +0 -0
  83. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/docs/AGENT_UI_E2E.md +0 -0
  84. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/docs/AGENT_UI_RECON.md +0 -0
  85. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/docs/ARCHITECTURE.md +0 -0
  86. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/docs/AUTHENTICATION.md +0 -0
  87. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/docs/CHARACTER.md +0 -0
  88. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/docs/CHARACTER_RECON.md +0 -0
  89. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/docs/CONFIGURATION.md +0 -0
  90. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/docs/DATA_LAYER.md +0 -0
  91. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/docs/DEBUGGING.md +0 -0
  92. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/docs/DEMOS.md +0 -0
  93. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/docs/DEVELOPMENT.md +0 -0
  94. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/docs/E2E_TESTING.md +0 -0
  95. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/docs/EXTERNAL_STORAGE.md +0 -0
  96. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/docs/GITHUB.md +0 -0
  97. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/docs/GOVERNANCE_BENCHMARK.md +0 -0
  98. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/docs/IMAGE_UPSCALE_RECON.md +0 -0
  99. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/docs/INSTRUCTIONS.md +0 -0
  100. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/docs/LIVE_VERIFICATION_data_layer.md +0 -0
  101. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/docs/LIVE_VERIFICATION_image_batch.md +0 -0
  102. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/docs/LIVE_VERIFICATION_v0.10.0.md +0 -0
  103. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/docs/LIVE_VERIFICATION_v0.11.0.md +0 -0
  104. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/docs/LIVE_VERIFICATION_v0.12.0.md +0 -0
  105. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/docs/LIVE_VERIFICATION_v0.13.0.md +0 -0
  106. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/docs/LIVE_VERIFICATION_v0.16.0.md +0 -0
  107. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/docs/LIVE_VERIFICATION_v0.17.0.md +0 -0
  108. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/docs/LIVE_VERIFICATION_v0.18.0.md +0 -0
  109. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/docs/LIVE_VERIFICATION_v0.19.0.md +0 -0
  110. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/docs/LIVE_VERIFICATION_v0.20.0.md +0 -0
  111. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/docs/LIVE_VERIFICATION_v0.20.1.md +0 -0
  112. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/docs/LIVE_VERIFICATION_v0.21.0.md +0 -0
  113. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/docs/LIVE_VERIFICATION_v0.22.0.md +0 -0
  114. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/docs/LIVE_VERIFICATION_v0.23.0.md +0 -0
  115. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/docs/LIVE_VERIFICATION_v0.24.0.md +0 -0
  116. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/docs/LIVE_VERIFICATION_v0.25.0.md +0 -0
  117. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/docs/LIVE_VERIFICATION_v0.26.0.md +0 -0
  118. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/docs/LIVE_VERIFICATION_v0.27.0.md +0 -0
  119. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/docs/LIVE_VERIFICATION_v0.27.1.md +0 -0
  120. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/docs/LIVE_VERIFICATION_v0.28.0.md +0 -0
  121. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/docs/LIVE_VERIFICATION_v0.29.0.md +0 -0
  122. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/docs/LIVE_VERIFICATION_v0.30.0.md +0 -0
  123. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/docs/LIVE_VERIFICATION_v0.7.0.md +0 -0
  124. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/docs/LIVE_VERIFICATION_v0.8.1.md +0 -0
  125. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/docs/LIVE_VERIFICATION_v0.9.0.md +0 -0
  126. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/docs/LIVE_VERIFICATION_v0.9.1.md +0 -0
  127. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/docs/LIVE_VERIFICATION_video_download.md +0 -0
  128. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/docs/MOVIE.md +0 -0
  129. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/docs/PROJECT_STATUS.md +0 -0
  130. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/docs/PROMPT_EXPANSION.md +0 -0
  131. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/docs/SECURITY.md +0 -0
  132. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/docs/TOOLS.md +0 -0
  133. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/docs/USER_GUIDE.md +0 -0
  134. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/docs/assets/demo-split-pf.gif +0 -0
  135. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/docs/assets/example-run.gif +0 -0
  136. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/docs/assets/examples.webp +0 -0
  137. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/docs/medium_tutorial.md +0 -0
  138. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/docs/schemas/movie-handoff.schema.json +0 -0
  139. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/docs/sonar-cleanup-tracker.md +0 -0
  140. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/docs/superpowers/plans/2026-06-12-issue-174-library-ui-attach/PLAN.md +0 -0
  141. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/docs/superpowers/plans/2026-06-22-mcp-server/PLAN.md +0 -0
  142. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/docs/superpowers/plans/2026-06-22-mcp-server/PREDICT.md +0 -0
  143. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/docs/superpowers/plans/2026-06-22-mcp-server/SCENARIO.md +0 -0
  144. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/docs/superpowers/plans/2026-06-22-prompt-expansion/PLAN.md +0 -0
  145. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/docs/superpowers/plans/2026-06-22-prompt-expansion/PREDICT.md +0 -0
  146. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/docs/superpowers/plans/2026-06-22-prompt-expansion/SCENARIO.md +0 -0
  147. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/docs/superpowers/plans/2026-06-24-gflow-studio-scaffold/PLAN.md +0 -0
  148. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/docs/superpowers/plans/2026-06-24-rest-api-layer/PLAN.md +0 -0
  149. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/docs/superpowers/plans/2026-06-26-mcp-e2e-test/PLAN.md +0 -0
  150. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/docs/superpowers/plans/2026-07-09-camoufox-adoption/PLAN.md +0 -0
  151. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/docs/superpowers/research/2026-06-27-tool-abstraction-evaluation.md +0 -0
  152. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/docs/superpowers/specs/2026-06-29-issue-assessment-workflow-design.md +0 -0
  153. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/docs/superpowers/spikes/2026-07-09-camoufox-waf-403.md +0 -0
  154. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/examples/README.md +0 -0
  155. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/examples/batch_from_config.py +0 -0
  156. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/examples/multi_prompt_t2i.py +0 -0
  157. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/examples/sample_config.json +0 -0
  158. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/examples/sample_prompts.txt +0 -0
  159. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/examples/single_image_t2i.py +0 -0
  160. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/examples/workflow_chain.py +0 -0
  161. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/llms.txt +0 -0
  162. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/samples/README.md +0 -0
  163. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/samples/captured/01_upload_image.json +0 -0
  164. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/samples/captured/02_batchAsyncGenerateVideoText.json +0 -0
  165. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/samples/captured/03_batchCheckAsyncVideoGenerationStatus.json +0 -0
  166. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/samples/captured/04_archive_workflow.json +0 -0
  167. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/samples/captured/05_createProject.json +0 -0
  168. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/samples/captured/06_batchGenerateImages.json +0 -0
  169. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/samples/captured/07_batchGenerateImages_seeded.json +0 -0
  170. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/samples/captured/08_batchAsyncGenerateVideoStartAndEndImage.json +0 -0
  171. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/samples/captured/09_batchAsyncGenerateVideoReferenceImages.json +0 -0
  172. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/samples/captured/10_batchCheckAsyncVideoGenerationStatus_successful.json +0 -0
  173. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/samples/captured/11_batchCheckAsyncVideoGenerationStatus_failed.json +0 -0
  174. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/samples/captured/12_create_scene.json +0 -0
  175. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/samples/captured/13_sceneWorkflows_update.json +0 -0
  176. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/samples/captured/14_get_scene_workflows.json +0 -0
  177. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/samples/captured/15_commit_flowWorkflow.json +0 -0
  178. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/scripts/ci/check_doc_links.py +0 -0
  179. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/scripts/ci/check_materiality.py +0 -0
  180. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/scripts/ci/check_repo_hygiene.py +0 -0
  181. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/scripts/debug_editor.py +0 -0
  182. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/scripts/debug_gen_settings.py +0 -0
  183. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/scripts/debug_settings.py +0 -0
  184. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/scripts/dev/_recording_client.py +0 -0
  185. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/scripts/dev/_spike_common.py +0 -0
  186. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/scripts/dev/active_plan.py +0 -0
  187. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/scripts/dev/analyze_agent_ui_capture.py +0 -0
  188. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/scripts/dev/capture_i2v_frame_slots_dom.py +0 -0
  189. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/scripts/dev/capture_i2v_intercept_submit.py +0 -0
  190. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/scripts/dev/capture_i2v_model_select_repro.py +0 -0
  191. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/scripts/dev/capture_i2v_post_bind_state.py +0 -0
  192. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/scripts/dev/capture_image_add_media_dom.py +0 -0
  193. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/scripts/dev/capture_locale_invariants.py +0 -0
  194. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/scripts/dev/cdp_drive_and_probe.py +0 -0
  195. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/scripts/dev/character_create_spike.py +0 -0
  196. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/scripts/dev/character_create_spike_v2.py +0 -0
  197. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/scripts/dev/dump_character_selectors.js +0 -0
  198. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/scripts/dev/make_project.py +0 -0
  199. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/scripts/dev/materiality_backtest.py +0 -0
  200. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/scripts/dev/monitor_pr_38.py +0 -0
  201. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/scripts/dev/patch_character.py +0 -0
  202. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/scripts/dev/skillopt/README.md +0 -0
  203. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/scripts/dev/skillopt/harness.py +0 -0
  204. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/scripts/dev/skillopt/tasks.json +0 -0
  205. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/scripts/dev/spike_char_editor_dom.py +0 -0
  206. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/scripts/dev/spike_char_gen_capture.py +0 -0
  207. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/scripts/dev/spike_image_upscale_capture.py +0 -0
  208. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/scripts/dev/spike_image_upscale_drive.py +0 -0
  209. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/scripts/dev/spike_image_upscale_recaptcha_action.py +0 -0
  210. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/scripts/dev/spike_image_upscale_rest_probe.py +0 -0
  211. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/scripts/dev/spike_issue170_picker_locale_recon.py +0 -0
  212. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/scripts/dev/spike_issue174_library_ui_recon.py +0 -0
  213. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/scripts/dev/spike_movie_entity_recon.py +0 -0
  214. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/scripts/dev/spike_movie_gen_capture.py +0 -0
  215. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/scripts/dev/spike_movie_picker_select.py +0 -0
  216. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/scripts/dev/spike_movie_voice_list.py +0 -0
  217. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/scripts/dev/spike_patch_entity.py +0 -0
  218. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/scripts/dev/spike_patchright.py +0 -0
  219. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/scripts/diag/README.md +0 -0
  220. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/scripts/diag/capture_flow_traffic.py +0 -0
  221. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/scripts/diag/memory_profile.py +0 -0
  222. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/scripts/diag/recaptcha_mint.py +0 -0
  223. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/scripts/e2e/agentic_image_e2e.ps1 +0 -0
  224. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/scripts/e2e/capture_agent_toggle.py +0 -0
  225. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/scripts/record_demo.ps1 +0 -0
  226. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/scripts/smoke_image.py +0 -0
  227. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/scripts/smoke_real_chrome_image.py +0 -0
  228. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/scripts/smoke_video_editor.py +0 -0
  229. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/scripts/smoke_worker_style.py +0 -0
  230. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/scripts/spike_waf_camoufox.py +0 -0
  231. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/scripts/verify_chrome_auth_viability.py +0 -0
  232. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/skills/README.md +0 -0
  233. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/skills/issue-assessment/SKILL.md +0 -0
  234. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/skills/issue-resolve/SKILL.md +0 -0
  235. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/skills/plan/SKILL.md +0 -0
  236. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/skills/pr-council-review/SKILL.md +0 -0
  237. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/skills/predict/SKILL.md +0 -0
  238. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/skills/scenario/SKILL.md +0 -0
  239. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/skills/status/SKILL.md +0 -0
  240. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/sonar-project.properties +0 -0
  241. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/__main__.py +0 -0
  242. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/_cli_helpers.py +0 -0
  243. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/api/__init__.py +0 -0
  244. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/api/_engine.py +0 -0
  245. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/api/_retry.py +0 -0
  246. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/api/_sapisidhash.py +0 -0
  247. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/api/character.py +0 -0
  248. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/api/client.py +0 -0
  249. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/api/dto.py +0 -0
  250. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/api/image.py +0 -0
  251. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/api/image_upscale.py +0 -0
  252. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/api/recaptcha.py +0 -0
  253. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/api/routes.py +0 -0
  254. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/api/scene.py +0 -0
  255. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/api/transports/__init__.py +0 -0
  256. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/api/transports/_common.py +0 -0
  257. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/api/transports/_fingerprint.py +0 -0
  258. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/api/transports/base.py +0 -0
  259. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/api/transports/drivers/__init__.py +0 -0
  260. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/api/transports/drivers/base.py +0 -0
  261. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/api/transports/drivers/factory.py +0 -0
  262. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/api/transports/experimental/__init__.py +0 -0
  263. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/api/transports/experimental/bearer.py +0 -0
  264. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/api/transports/experimental/evaluate_fetch.py +0 -0
  265. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/api/transports/experimental/sapisidhash.py +0 -0
  266. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/api/transports/ui_automation.py +0 -0
  267. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/auth/__init__.py +0 -0
  268. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/auth/base.py +0 -0
  269. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/auth/cookies.py +0 -0
  270. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/auth/factory.py +0 -0
  271. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/auth/internal_chromium.py +0 -0
  272. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/auth/real_chrome.py +0 -0
  273. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/auth/strategies.py +0 -0
  274. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/auth/verification.py +0 -0
  275. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/browser_manager.py +0 -0
  276. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/chain.py +0 -0
  277. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/chain_manifest.py +0 -0
  278. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/cli.py +0 -0
  279. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/cli_character.py +0 -0
  280. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/cli_data.py +0 -0
  281. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/cli_instructions.py +0 -0
  282. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/cli_models.py +0 -0
  283. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/cli_movie.py +0 -0
  284. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/cli_run.py +0 -0
  285. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/cli_scene.py +0 -0
  286. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/cli_tools.py +0 -0
  287. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/composition.py +0 -0
  288. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/config.py +0 -0
  289. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/data/__init__.py +0 -0
  290. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/data/chain_repo.py +0 -0
  291. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/data/migrations/0001_initial.sql +0 -0
  292. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/data/migrations/0002_add_cloud_storage.sql +0 -0
  293. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/data/migrations/0003_add_scene_tables.sql +0 -0
  294. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/data/migrations/0004_add_scene_output_path.sql +0 -0
  295. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/data/migrations/0005_add_chain_links.sql +0 -0
  296. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/data/migrations/0006_add_operations_metadata.sql +0 -0
  297. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/data/migrations/0007_queue.sql +0 -0
  298. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/data/migrations/0008_add_operation_expanded_prompt.sql +0 -0
  299. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/data/migrations/__init__.py +0 -0
  300. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/data/models.py +0 -0
  301. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/data/queries.py +0 -0
  302. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/data/redaction.py +0 -0
  303. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/data/repository.py +0 -0
  304. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/data/store.py +0 -0
  305. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/exceptions.py +0 -0
  306. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/json_output.py +0 -0
  307. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/manifest.py +0 -0
  308. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/mcp/__init__.py +0 -0
  309. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/mcp/prompts.py +0 -0
  310. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/mcp/resources.py +0 -0
  311. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/mcp/server.py +0 -0
  312. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/mcp/tools.py +0 -0
  313. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/media.py +0 -0
  314. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/movie_manifest.py +0 -0
  315. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/observability.py +0 -0
  316. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/paths.py +0 -0
  317. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/profile_store.py +0 -0
  318. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/services/__init__.py +0 -0
  319. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/services/character_create.py +0 -0
  320. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/storage.py +0 -0
  321. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/tools/__init__.py +0 -0
  322. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/tools/banned.py +0 -0
  323. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/tools/builtin/__init__.py +0 -0
  324. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/tools/builtin/creative-director.toml +0 -0
  325. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/tools/expander.py +0 -0
  326. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/tools/invocation.py +0 -0
  327. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/tools/loader.py +0 -0
  328. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/tools/registry.py +0 -0
  329. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/tools/runtime.py +0 -0
  330. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/tools/spec.py +0 -0
  331. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/ui/app.py +0 -0
  332. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/ui/server.py +0 -0
  333. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/src/gflow_cli/worker/queue.py +0 -0
  334. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tasks/lessons.md +0 -0
  335. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/test_assets/sample_batch.json +0 -0
  336. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/test_assets/sample_batch.tsv +0 -0
  337. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/test_assets/sample_batch_invalid.tsv +0 -0
  338. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/__init__.py +0 -0
  339. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/api/__init__.py +0 -0
  340. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/api/fixtures/character_gen_response.json +0 -0
  341. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/api/fixtures/patch_entity_response.json +0 -0
  342. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/api/test_aisandbox_auth_error.py +0 -0
  343. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/api/test_aisandbox_auth_headers.py +0 -0
  344. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/api/test_bearer_redaction.py +0 -0
  345. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/api/test_character.py +0 -0
  346. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/api/test_client.py +0 -0
  347. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/api/test_client_character.py +0 -0
  348. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/api/test_client_delete_characters.py +0 -0
  349. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/api/test_client_generate_character.py +0 -0
  350. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/api/test_client_image.py +0 -0
  351. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/api/test_client_launch_kwargs.py +0 -0
  352. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/api/test_client_patch_entity.py +0 -0
  353. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/api/test_client_scene.py +0 -0
  354. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/api/test_client_upscale.py +0 -0
  355. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/api/test_concurrency.py +0 -0
  356. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/api/test_dto.py +0 -0
  357. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/api/test_engine.py +0 -0
  358. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/api/test_image.py +0 -0
  359. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/api/test_image_dto.py +0 -0
  360. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/api/test_image_upscale.py +0 -0
  361. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/api/test_post_json_aisandbox_auth.py +0 -0
  362. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/api/test_recaptcha.py +0 -0
  363. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/api/test_retry.py +0 -0
  364. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/api/test_routes.py +0 -0
  365. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/api/test_routes_character.py +0 -0
  366. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/api/test_routes_scene.py +0 -0
  367. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/api/test_sapisidhash_helper.py +0 -0
  368. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/api/test_scene_models.py +0 -0
  369. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/api/test_video_request.py +0 -0
  370. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/api/transports/__init__.py +0 -0
  371. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/api/transports/conftest.py +0 -0
  372. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/api/transports/drivers/__init__.py +0 -0
  373. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/api/transports/drivers/test_factory.py +0 -0
  374. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/api/transports/test_base.py +0 -0
  375. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/api/transports/test_bearer.py +0 -0
  376. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/api/transports/test_common.py +0 -0
  377. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/api/transports/test_evaluate_fetch.py +0 -0
  378. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/api/transports/test_factory.py +0 -0
  379. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/api/transports/test_fingerprint.py +0 -0
  380. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/api/transports/test_sapisidhash.py +0 -0
  381. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/api/transports/test_selector_symmetry.py +0 -0
  382. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/api/transports/test_transport_timeout.py +0 -0
  383. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/api/transports/test_ui_automation.py +0 -0
  384. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/api/transports/test_ui_automation_batch.py +0 -0
  385. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/api/transports/test_ui_automation_image_mode.py +0 -0
  386. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/api/transports/test_ui_character_editor.py +0 -0
  387. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/auth/strategies/test_factory.py +0 -0
  388. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/auth/strategies/test_strategies.py +0 -0
  389. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/auth/test_cookies.py +0 -0
  390. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/auth/test_verification.py +0 -0
  391. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/cli/__init__.py +0 -0
  392. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/cli/test_cli_auth_list.py +0 -0
  393. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/cli/test_cli_character.py +0 -0
  394. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/cli/test_cli_character_create.py +0 -0
  395. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/cli/test_cli_data.py +0 -0
  396. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/cli/test_cli_image_seed_removed.py +0 -0
  397. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/cli/test_cli_image_selector_drift.py +0 -0
  398. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/cli/test_cli_image_upscale.py +0 -0
  399. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/cli/test_cli_instructions.py +0 -0
  400. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/cli/test_cli_models.py +0 -0
  401. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/cli/test_cli_movie.py +0 -0
  402. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/cli/test_cli_run.py +0 -0
  403. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/cli/test_cli_scene.py +0 -0
  404. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/cli/test_cli_tools.py +0 -0
  405. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/cli/test_cli_video_chain.py +0 -0
  406. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/cli/test_error_handling.py +0 -0
  407. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/cli/test_helpers.py +0 -0
  408. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/cli/test_movie_manifest.py +0 -0
  409. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/cli/test_movie_manifest_style_variants.py +0 -0
  410. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/cli/test_settings_validation.py +0 -0
  411. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/cli/test_t2i_multi_prompt.py +0 -0
  412. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/composition/test_character.py +0 -0
  413. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/composition/test_compose_prompt.py +0 -0
  414. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/composition/test_handoff.py +0 -0
  415. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/composition/test_style_variants.py +0 -0
  416. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/composition/test_style_variants_e2e.py +0 -0
  417. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/conftest.py +0 -0
  418. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/data/__init__.py +0 -0
  419. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/data/test_chain_repo.py +0 -0
  420. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/data/test_find_incomplete_character.py +0 -0
  421. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/data/test_models.py +0 -0
  422. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/data/test_packaging.py +0 -0
  423. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/data/test_recorder_character.py +0 -0
  424. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/data/test_redaction.py +0 -0
  425. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/data/test_repository.py +0 -0
  426. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/data/test_scene_persistence.py +0 -0
  427. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/data/test_settings_and_errors.py +0 -0
  428. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/data/test_store_migrations.py +0 -0
  429. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/dev/test_recording_client.py +0 -0
  430. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/e2e/__init__.py +0 -0
  431. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/e2e/conftest.py +0 -0
  432. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/e2e/test_aisandbox_auth_live.py +0 -0
  433. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/e2e/test_auth_verification_e2e.py +0 -0
  434. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/e2e/test_chain_e2e.py +0 -0
  435. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/e2e/test_character_create_e2e.py +0 -0
  436. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/e2e/test_daemon_e2e.py +0 -0
  437. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/e2e/test_data_layer_e2e.py +0 -0
  438. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/e2e/test_i2v_flags_e2e.py +0 -0
  439. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/e2e/test_image_batch_e2e.py +0 -0
  440. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/e2e/test_image_i2i_ref_cap_e2e.py +0 -0
  441. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/e2e/test_json_output_e2e.py +0 -0
  442. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/e2e/test_live_agentic_instructions.py +0 -0
  443. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/e2e/test_locale_selectors_e2e.py +0 -0
  444. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/e2e/test_scene_compose_live.py +0 -0
  445. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/e2e/test_tools_e2e.py +0 -0
  446. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/e2e/test_transports_e2e.py +0 -0
  447. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/e2e/test_video_r2v_ref_cap_e2e.py +0 -0
  448. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/e2e/test_video_t2v_e2e.py +0 -0
  449. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/features/__init__.py +0 -0
  450. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/features/auth.feature +0 -0
  451. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/features/auth_login.feature +0 -0
  452. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/features/character_create.feature +0 -0
  453. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/features/character_read.feature +0 -0
  454. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/features/conftest.py +0 -0
  455. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/features/image.feature +0 -0
  456. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/features/image_upscale.feature +0 -0
  457. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/features/instructions.feature +0 -0
  458. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/features/locale_picker_include.feature +0 -0
  459. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/features/test_auth_login_steps.py +0 -0
  460. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/features/test_auth_steps.py +0 -0
  461. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/features/test_character_create_steps.py +0 -0
  462. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/features/test_character_read_steps.py +0 -0
  463. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/features/test_image_steps.py +0 -0
  464. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/features/test_image_upscale_steps.py +0 -0
  465. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/features/test_instructions_steps.py +0 -0
  466. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/features/test_locale_picker_include_steps.py +0 -0
  467. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/features/test_step_collision_guard.py +0 -0
  468. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/features/test_video_chain_steps.py +0 -0
  469. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/features/video_agent_ui.feature +0 -0
  470. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/features/video_chain.feature +0 -0
  471. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/fixtures/__init__.py +0 -0
  472. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/fixtures/seeded_catalog.py +0 -0
  473. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/image_batch/__init__.py +0 -0
  474. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/integration/__init__.py +0 -0
  475. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/integration/conftest.py +0 -0
  476. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/integration/constants.py +0 -0
  477. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/integration/test_storage_gcs.py +0 -0
  478. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/integration/test_storage_s3.py +0 -0
  479. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/mcp/__init__.py +0 -0
  480. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/mcp/conftest.py +0 -0
  481. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/mcp/test_cli_parity.py +0 -0
  482. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/mcp/test_server.py +0 -0
  483. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/mcp/test_stdio_transport.py +0 -0
  484. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/mcp/test_tools_helpers.py +0 -0
  485. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/mcp/test_tools_instructions.py +0 -0
  486. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/mcp/test_tools_wired.py +0 -0
  487. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/scripts/test_analyze_agent_ui_capture.py +0 -0
  488. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/scripts/test_capture_locale_invariants.py +0 -0
  489. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/scripts/test_check_materiality.py +0 -0
  490. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/scripts/test_check_repo_hygiene.py +0 -0
  491. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/scripts/test_materiality_backtest.py +0 -0
  492. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/services/__init__.py +0 -0
  493. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/services/test_character_create_redaction.py +0 -0
  494. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/services/test_character_create_saga.py +0 -0
  495. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/services/test_character_gen_no_direct_post.py +0 -0
  496. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/smoke/__init__.py +0 -0
  497. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/smoke/test_profile_account_smoke.py +0 -0
  498. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/smoke/test_real_flow.py +0 -0
  499. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/test_auth.py +0 -0
  500. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/test_browser_manager.py +0 -0
  501. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/test_chain.py +0 -0
  502. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/test_chain_manifest.py +0 -0
  503. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/test_cli_data.py +0 -0
  504. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/test_config.py +0 -0
  505. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/test_conftest_isolation.py +0 -0
  506. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/test_data_queries.py +0 -0
  507. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/test_documentation_gate.py +0 -0
  508. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/test_errors_403.py +0 -0
  509. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/test_json_output.py +0 -0
  510. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/test_manifest.py +0 -0
  511. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/test_marker_registry.py +0 -0
  512. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/test_media.py +0 -0
  513. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/test_observability.py +0 -0
  514. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/test_paths.py +0 -0
  515. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/test_profile_store.py +0 -0
  516. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/test_smoke.py +0 -0
  517. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/tools/__init__.py +0 -0
  518. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/tools/test_banned.py +0 -0
  519. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/tools/test_expander.py +0 -0
  520. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/tools/test_invocation.py +0 -0
  521. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/tools/test_loader.py +0 -0
  522. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/tools/test_registry.py +0 -0
  523. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/tools/test_runtime.py +0 -0
  524. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/tools/test_spec.py +0 -0
  525. {gflow_cli-0.30.0 → gflow_cli-0.32.0}/tests/ui/test_app.py +0 -0
@@ -57,7 +57,7 @@ Or invoke the wrapper: `/gflow:check`.
57
57
 
58
58
  - Type hints everywhere; `pyright` strict on `src/gflow_cli`.
59
59
  - Structured logging only (`structlog`) — **never** raw `print()` or `import logging` in `src/`.
60
- - Errors as RFC 9457 Problem Details with stable per-class exit codes (3–25, e.g. 16 is the `DataStoreError` family, 19 `SceneConcatError`, 20 `FrameExtractionError`, 21 `ChainPartialError`, 22 `UpscaleUnavailableError`, 25 `FlowAgentUiError`). See `src/gflow_cli/errors.py::EXIT_CODE_MAP` for the complete mapping.
60
+ - Errors as RFC 9457 Problem Details with stable per-class exit codes (3–27, e.g. 16 is the `DataStoreError` family, 19 `SceneConcatError`, 20 `FrameExtractionError`, 21 `ChainPartialError`, 22 `UpscaleUnavailableError`, 25 `FlowAgentUiError`). See `src/gflow_cli/errors.py::EXIT_CODE_MAP` for the complete mapping.
61
61
  - 100-char line length, `ruff` configured. Imports sorted by `ruff` (isort rules).
62
62
  - **MCP & CLI Schema Symmetry**: Any updates or additions to user-facing CLI command parameters (e.g., `gflow image t2i`, `gflow video`) must be mirrored in the corresponding MCP tool definitions. Never add option/argument fields to Click commands without updating the MCP server implementation. This symmetry is enforced programmatically in CI via `tests/mcp/test_cli_parity.py` (every CLI leaf command needs a mapped MCP tool or an explicit, reasoned exemption) plus the schema checks in `tests/mcp/test_server.py`.
63
63
 
@@ -7,6 +7,27 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.32.0] — 2026-07-11
11
+
12
+ ### Added
13
+
14
+ - **`gflow video i2v` accepts an in-project asset media UUID for `--initial-frame` / `--end-frame` (and the positional IMAGE).** A UUID-shaped value selects the already-existing Flow asset in place via the same `_select_existing_asset` picker the image `--ref` flow uses (#282 scroll/search fixes included) instead of forcing a duplicate local-file upload — the duplicate-asset pileup and per-run re-upload from the 2026-07-11 chalkboard pilot. Pair with `--project` so the asset's project is the one generated in; a UUID that can't be located in the picker fails with `TransportTimeoutError` (exit 9) naming the slot and UUID (#287).
15
+
16
+ ### Fixed
17
+
18
+ - **A Flow upload-endpoint rejection is now a typed error instead of "Unexpected error." (exit 1).** An `uploadImage` 4xx during frame/reference attach (observed live: one JPEG rejected with HTTP 400 while byte-identical-format siblings uploaded fine) raised a bare `RuntimeError` that fell through to the generic handler with no hint the *input image* was refused. It now raises the new `MediaUploadRejectedError` (**exit code 27**, RFC 9457 type `media-upload-rejected`) with a re-encode remediation hint (`ffmpeg -q:v 2 -map_metadata -1`) (#287).
19
+ - **An explicit `--duration` that cannot be applied now fails fast instead of silently producing a clip of Flow's default length.** When the video settings panel's duration tab probe missed (observed 3/3 on a live 2026-07-11 Frames-submode run: `--duration 4` returned an 8-second clip and the JSON result reported success), `_select_video_duration` demoted the failure to a warning and generation continued on Flow's default. Duration is a contract parameter — downstream timeline math sizes cuts from the requested value — so a probe miss with an explicit `--duration` now raises `UiSelectorDriftError` (**exit code 23**, the #183 selector-drift semantics) with a `debug_no_duration_tab.png` viewport screenshot and an omit-`--duration` remediation hint. Omitting `--duration` is unaffected. Root cause confirmed live 2026-07-11: the duration control is absent from the affected cohort's settings popover (#288, #289).
20
+
21
+ ## [0.31.0] — 2026-07-10
22
+
23
+ ### Fixed
24
+
25
+ - **Agentic image generation no longer risks attributing a pre-existing project asset to the current request.** `await_images` settled its new-media baseline with a single DOM scrape, which could miss a lazily-rendered pre-existing tile and let `_build_generated_images` slice an arbitrary UUID out of an unordered set as "the" generated image — the 2026-07-10 production incident: an old project logo was silently downloaded and reported as a fresh generation. The baseline is now the **union of two `_scrape_img_srcs` passes** one poll interval apart, absorbing lazy-render stragglers before they're mistaken for new media, and if more new UUIDs still appear than were requested, `await_images` now fails fast with the new `MediaAttributionError` (**exit code 26**, RFC 9457 type `media-attribution`) naming every candidate UUID and the expected count instead of guessing (#281).
26
+ - **A pre-download attribution guard now runs ahead of every image download, with `DataIntegrityError` escalated instead of warned.** Even a driver that never hits the agentic ambiguity check above can still hand back a `flow_media_id` already recorded for the profile. `OperationRecorder.verify_media_attribution()` (called from `cli_image.py`, `image_batch.py`'s manifest batch path, and `FlowWorker.process_task`) checks `is_media_recorded()` before `_download_images` and raises `MediaAttributionError` rather than downloading — it also now rejects an intra-batch duplicate `flow_media_id` (the classic transport can return the same media twice in one submission) with no DB lookup needed. Separately, a `DataIntegrityError` from the recorder's `UNIQUE(profile_name, flow_media_id)` constraint — previously caught by the generic `DataStoreError` path and reported as a warn-only "Generated media was saved, but local history was not updated." — now escalates to the same `MediaAttributionError` when (and only when) the failing write is that exact constraint (`route == "data.upsert_asset"`); any other `DataIntegrityError` (e.g. an unrelated `insert_operation`/`link_operation_asset` failure) falls through to the ordinary warn-and-continue path instead of being mislabeled as a media collision. The escalation message now names the full candidate set of `flow_media_id`s / saved paths ("one of ...") rather than always fingering the first image, since the colliding index can't be recovered from sqlite's bare constraint violation (#281).
27
+ - **The pre-download attribution guard and the collision-escalation logic are each now a single shared implementation instead of three near-identical copies.** Both originally shipped duplicated across `cli_image.py`, `image_batch.py`, and `worker/daemon.py` (each call site already held a recorder instance), which tripped SonarCloud's duplicated-lines gate. The guard is consolidated onto `OperationRecorder.verify_media_attribution()`; the escalation is consolidated onto the new `gflow_cli.data.recorder.escalate_asset_collision()` — both with no behavior change beyond the route-scoping and intra-batch-duplicate fixes above (#281, #282, #283).
28
+ - **`gflow image batch` (the manifest path) now honors `--continue-on-error` for a media-attribution collision.** A collision on one row — from either the pre-download guard or the post-download collision escalation — used to propagate out of the whole batch run regardless of `--continue-on-error`, discarding every other row's already-completed outcome. With `--continue-on-error` the colliding row is now marked as a normal "fail" outcome (nothing was downloaded/recorded for that row) and the batch continues; without it, the collision still aborts the run as before (#281, #282).
29
+ - **`--ref <uuid>` picker selection now resolves every ref, not just the first.** `_select_existing_asset` gave up as soon as a tile wasn't in the initial viewport or surfaced by the display-name search, so any `--ref` after the first raised `TransportTimeoutError` once the virtualised (react-virtuoso) media grid hadn't rendered it yet. It now falls back to scrolling and re-checking between scrolls, mirroring the entity picker's `_find_picker_entity_tile` strategy, and `_attach_image_uuid_refs` clears the picker search input at the start of every ref iteration so a search typed while resolving one ref can't shadow the next ref's tile lookup. `_select_existing_asset` itself now also clears a failed display-name search before falling back to scrolling, so it doesn't scroll a grid still filtered by the failed term (#282).
30
+
10
31
  ## [0.30.0] — 2026-07-09
11
32
 
12
33
  ### Added
@@ -1898,7 +1919,9 @@ shell-script template that branches on these codes.
1898
1919
 
1899
1920
  First skeleton. Not functional end-to-end yet.
1900
1921
 
1901
- [Unreleased]: https://github.com/ffroliva/gflow-cli/compare/v0.30.0...HEAD
1922
+ [Unreleased]: https://github.com/ffroliva/gflow-cli/compare/v0.32.0...HEAD
1923
+ [0.32.0]: https://github.com/ffroliva/gflow-cli/compare/v0.31.0...v0.32.0
1924
+ [0.31.0]: https://github.com/ffroliva/gflow-cli/compare/v0.30.0...v0.31.0
1902
1925
  [0.30.0]: https://github.com/ffroliva/gflow-cli/compare/v0.29.0...v0.30.0
1903
1926
  [0.29.0]: https://github.com/ffroliva/gflow-cli/compare/v0.28.0...v0.29.0
1904
1927
  [0.28.0]: https://github.com/ffroliva/gflow-cli/compare/v0.27.1...v0.28.0
@@ -14,6 +14,63 @@ Living list of behaviour that's broken, surprising, or limited by design — alo
14
14
 
15
15
  ## Open
16
16
 
17
+ ### Flow's `uploadImage` endpoint rejects some JPEGs with HTTP 400 (metadata-sensitive)
18
+
19
+ - **Status:** Open ([#287](https://github.com/ffroliva/gflow-cli/issues/287))
20
+ - **Severity:** Low (typed + remediable) · **Affected:** i2v frame / reference uploads
21
+
22
+ Observed live 2026-07-11: one JPEG was rejected with HTTP 400 while
23
+ byte-identical-format siblings uploaded fine; re-encoding with
24
+ `ffmpeg -q:v 2 -map_metadata -1` fixed it, implicating a metadata segment.
25
+ Since #290 the rejection raises `MediaUploadRejectedError` (exit 27) with that
26
+ remediation instead of a generic "Unexpected error." (exit 1). **Workaround:**
27
+ re-encode the file, or reference the already-in-project asset by media UUID
28
+ (`--initial-frame <UUID> --project <id>`). Root cause of Flow's metadata
29
+ sensitivity is unidentified.
30
+
31
+ ### i2v frame-slot picker selection by UUID — RESOLVED live 2026-07-11
32
+
33
+ - **Status:** **Verified live** ([#287](https://github.com/ffroliva/gflow-cli/issues/287) / PR [#290](https://github.com/ffroliva/gflow-cli/pull/290))
34
+ - **Affected:** `gflow video i2v --initial-frame/--end-frame <UUID>`
35
+
36
+ #290 routes i2v frame slots through `_select_existing_asset` (the UUID picker
37
+ live-proven in the **Add-Media** dialog: v0.26.0 i2i-by-UUID, #282 scroll
38
+ fixes). The **frame-slot** dialog carried a negative prior — #237's
39
+ name-search there never surfaced generated media (v0.25.0 rework) — but the
40
+ thumbnail-URL tile match succeeds where name search failed. Live evidence
41
+ (2026-07-11, denon82): `frame_ref_attached {slot: Start}` → wire capture on
42
+ `batchAsyncGenerateVideoStartImage` with the asset's `startImage` bound →
43
+ SUCCESSFUL 720×1280 mp4; **zero** `image_uploaded` events (no duplicate
44
+ upload). Negative check: a foreign UUID exits 9 pre-generation with a
45
+ `debug_frame_ref_miss_start.png` screenshot. Caveat that stands: the asset's
46
+ project must be entered via `--project`, and projects that open in the
47
+ full-page media-library UI (#174) can fail earlier at `mode_switch_trigger`.
48
+
49
+ ### Video duration tab probe misses on the current Frames-submode DOM
50
+
51
+ - **Status:** Open ([#288](https://github.com/ffroliva/gflow-cli/issues/288))
52
+ - **Severity:** Medium · **Affected:** `gflow video` with an explicit `--duration`
53
+ on at least some Classic-profile cohorts (3/3 miss on a live 2026-07-11 run)
54
+
55
+ The `duration_tab` selector cascade (`[role='tab']:text-is('4s')` /
56
+ `:has-text('4s')`) fails to match on Flow's current Frames-submode settings
57
+ panel. Pre-fix this silently produced a clip of Flow's default length; since
58
+ the #289 fix the run fails fast with `UiSelectorDriftError` (exit 23) and a
59
+ `debug_no_duration_tab.png` screenshot — live-verified 2026-07-11 on the
60
+ denon82 profile (aborted pre-submit, saving the 10-credit generation).
61
+ **Workaround:** omit `--duration` to accept Flow's default.
62
+
63
+ **Root cause (confirmed live 2026-07-11, screenshot evidence on #288): the
64
+ duration control is ABSENT from this cohort's settings popover** — the panel
65
+ renders mode tabs (Imagem/Video), sub-mode (Frames/Elementos), aspect
66
+ (9:16/16:9), count (1x–x4), and the model dropdown (Veo 3.1 - Lite), and
67
+ nothing else. The earlier locale hypothesis is refuted: the UI renders in
68
+ Portuguese and the sibling count tabs (`1x`/`x2`) match fine; there is simply
69
+ no duration row to click. Whether Flow removed clip-length selection for this
70
+ cohort/model or moved it elsewhere is unknown — until that's answered,
71
+ `--duration` cannot be honored on affected cohorts and the fail-fast is the
72
+ correct behavior, not a selector bug to patch.
73
+
17
74
  ### macOS: generation runs logged-out → HTTP 401, even with `--browser chrome`
18
75
 
19
76
  - **Status:** **RESOLVED in v0.23.0** ([#222](https://github.com/ffroliva/gflow-cli/issues/222),
@@ -663,6 +720,108 @@ key — surfaces as a `RuntimeError` that `auth/cookies.py` normalizes to
663
720
 
664
721
  ## Resolved
665
722
 
723
+ ### Agentic image generation could silently attribute a pre-existing project asset as the "generated" image
724
+
725
+ - **Status:** Resolved · **Severity:** Was-High (wrong file downloaded and reported as success, silently) · **Was-affecting:** the agentic driver through v0.30.0 (and, for the pre-download guard below, every transport) · **Fixed in:** unreleased (0.31.0) · **Tracked:** [#281](https://github.com/ffroliva/gflow-cli/issues/281); related picker fix [#282](https://github.com/ffroliva/gflow-cli/issues/282)
726
+
727
+ Discovered 2026-07-10 in a live production run: `gflow image t2i` under the
728
+ agentic driver downloaded an **old project logo** and reported it as a freshly
729
+ generated "portrait" — no error, just the pre-existing warn-only line
730
+ `"Generated media was saved, but local history was not updated."` — and 11
731
+ downstream `i2i` scenes were then anchored to the wrong file.
732
+
733
+ **Root cause — two defects in `await_images` (agentic driver):**
734
+ 1. The new-media baseline was a **single** DOM scrape (`_scrape_img_srcs`); a
735
+ pre-existing tile that rendered lazily (after generation had already
736
+ started) was missed by that scrape and then counted as "new" once it
737
+ appeared.
738
+ 2. `_build_generated_images` sliced an **unordered** UUID set down to
739
+ `expected_count` — an arbitrary pick when more "new" UUIDs were present
740
+ than were actually requested, with no signal for which UUID(s) belonged to
741
+ this generation.
742
+
743
+ **A third, independent gap** existed downstream of the driver: even a transport
744
+ that never hits the agentic DOM-scrape path above could still hand back a
745
+ `flow_media_id` already present in local history for the profile. That case
746
+ was caught by the generic `DataStoreError` path, which only warned and
747
+ continued — a silently duplicated/misattributed history row, not a hard
748
+ failure.
749
+
750
+ **Fix — three defense layers, all raising the new `MediaAttributionError`
751
+ (exit code 26, RFC 9457 type `media-attribution`) instead of a silent or
752
+ warn-only outcome:**
753
+ 1. **Baseline settle.** The baseline is now the **union of two
754
+ `_scrape_img_srcs` passes** one poll interval apart, absorbing lazy-render
755
+ stragglers before they can be mistaken for new media.
756
+ 2. **Ambiguity fail-fast.** If more new UUIDs still appear than were
757
+ requested, `await_images` raises `MediaAttributionError` naming every
758
+ candidate UUID and the expected count, rather than guessing via
759
+ `_build_generated_images`'s old arbitrary slice.
760
+ 3. **Pre-download attribution guard + collision escalation.**
761
+ `OperationRecorder.verify_media_attribution()` (called from `cli_image.py`,
762
+ `image_batch.py`'s manifest batch path, and the worker daemon's
763
+ `FlowWorker.process_task`; consolidated onto the recorder in #283 after
764
+ shipping as three near-identical module-level copies) checks
765
+ `is_media_recorded()` and raises before any download if the driver
766
+ returned a `flow_media_id` already recorded for the profile.
767
+ Separately, a `DataIntegrityError` from the recorder's
768
+ `UNIQUE(profile_name, flow_media_id)` constraint now escalates to
769
+ `MediaAttributionError` (naming the suspect file) instead of being caught
770
+ by the generic `DataStoreError` warn-only path.
771
+
772
+ Precedent for this class of fix: the `--model` silent no-op entry below (same
773
+ section) — an error the user sees beats a wrong artifact reported as success.
774
+
775
+ **Related, but distinct.** [#282](https://github.com/ffroliva/gflow-cli/issues/282)
776
+ fixed a separate defect in the same media-picker surface (`--ref <uuid>`
777
+ selection failing on any ref after the first once the virtualised
778
+ (react-virtuoso) grid needed to scroll to render it) — a picker-navigation
779
+ bug, not a data-integrity one. [#174](https://github.com/ffroliva/gflow-cli/issues/174)
780
+ (open, in the "Open" section above) is a Flow-side full-page media-library
781
+ UI rollout that breaks entity attach on affected accounts — a different
782
+ code path, but the same general theme that the media-picker surface needs
783
+ ongoing hardening.
784
+
785
+ **Residual risk (post-fix, not fully closed).** The two-pass baseline settle
786
+ narrows the window, it doesn't remove it: the agentic poll loop still stops
787
+ scraping the moment the new-UUID count on a single scrape equals the
788
+ requested count. A pre-existing tile that lazy-renders *after* the 0.5s
789
+ baseline settle but *before* the real generation actually completes
790
+ (generations take 30–60s) lands inside that window at exactly the expected
791
+ count — the ambiguity fail-fast in layer 2 only triggers on an *excess* of
792
+ new UUIDs, so it never sees this case. Layer 3's pre-download guard and
793
+ collision escalation then only catch it if the misattributed asset happens
794
+ to already be in **local** history for the profile — an asset created in the
795
+ Flow web UI, generated on another machine, or recorded under a different
796
+ profile DB has no local history row to collide with, so it can still slip
797
+ through all three layers: wrong file on disk, exit 0. Mitigations until this
798
+ is closed: run generations in a dedicated, low-asset project (fewer
799
+ pre-existing tiles means a smaller lazy-render population to collide with),
800
+ and visually verify anchor/canonical images before referencing them
801
+ downstream in `i2i`. Follow-up hardening (a break condition stable across
802
+ two consecutive scrapes, not one) is tracked upstream against this issue.
803
+
804
+ **Known gap: the shell multi-prompt path records no history at all.**
805
+ `gflow run --config <file>` and `gflow image t2i` with multiple prompts
806
+ (positional, `--prompts-file`, or `--stdin`) both go through
807
+ `image_batch.run_image_batch` / `run_one_image_prompt`, which never opens an
808
+ `OperationRecorder` or calls `record_generated_images` — no local history row
809
+ is written for these runs at all. Layer 1 (the agentic driver's two-pass
810
+ baseline settle + ambiguity fail-fast in `await_images`) still applies since
811
+ it lives in the transport, independent of recording. Layers 2 and 3
812
+ (`verify_media_attribution`'s pre-download guard and the post-download
813
+ collision escalation) both depend on local history via
814
+ `OperationRecorder.is_media_recorded()` / `record_generated_images()`, so
815
+ neither guard exists on this path — this is a pre-existing gap, not a
816
+ regression from this fix. `gflow image batch` (the manifest path, via
817
+ `run_manifest_image_batch`) already threads a recorder through and is covered
818
+ by all three layers. Follow-up tracked in #283.
819
+
820
+ **Workaround (pre-fix):** none — on an affected version, manually verify the
821
+ downloaded file matches the prompt before trusting a `t2i`/`i2i` result.
822
+
823
+ ---
824
+
666
825
  ### Profile named `default` is opaque — no Google account identity
667
826
 
668
827
  - **Status:** Resolved · **Severity:** Was-Low (UX confusion, no data loss) · **Was-affecting:** all versions through v0.9.x · **Fixed in:** v0.10.0 via PR #110 (2026-05-28) · **Tracked:** issue #92
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gflow-cli
3
- Version: 0.30.0
3
+ Version: 0.32.0
4
4
  Summary: Unofficial CLI for Google Flow — drive Veo image-to-video generations from the terminal.
5
5
  Project-URL: Homepage, https://github.com/ffroliva/gflow-cli
6
6
  Project-URL: Issues, https://github.com/ffroliva/gflow-cli/issues
@@ -122,7 +122,7 @@ Slash commands for Claude Code, stored in `.claude/commands/gflow/`. All prefixe
122
122
  **"A gflow command hangs / fails — where do I start?"** → [DEBUGGING § Quick reference](DEBUGGING.md#quick-reference)
123
123
  **"Flow's UI broke a selector — how do I diagnose it?"** → [DEBUGGING § Inspecting Flow's live UI](DEBUGGING.md#inspecting-flows-live-ui)
124
124
  **"What does each `ui_automation.*` log event mean?"** → [DEBUGGING § Listener & HTTP-layer debugging](DEBUGGING.md#listener--http-layer-debugging)
125
- **"What was actually live-verified for the latest release?"** → latest: [LIVE_VERIFICATION_v0.30.0](LIVE_VERIFICATION_v0.30.0.md) (**agentic-cohort image path + both fixes live-verified credit-free** — native 768×1376 stills, i2i-chain + canonical-ref identity hold; the character-create `DataIntegrityError` and the `prefer_classic` WARNING were observed live then fixed [recorder idempotent + INFO log]; MCP video-param feature deferred-with-reason on Veo credits, per the stills-only goal). Prior: [v0.29.0](LIVE_VERIFICATION_v0.29.0.md) (**persistent `gflow instructions` CRUD proven live e2e GREEN, credit-free** — 11-command sequence on a fresh project: add incl. `--ref <image-UUID>` attach, list/enable/disable, master toggle both ways, TOML `apply` destructive full-sync with `enabled=false` honored, `rm` with server card-id preserved across mutations; movie brief-sync code-path-verified via the same primitives, deferred-with-reason on credits; MCP `gflow_instructions_*` tools are thin adapters over the live-verified primitives). Prior: [v0.28.0](LIVE_VERIFICATION_v0.28.0.md) (**agent instructions `-i` now steer agentic generation — crayon e2e GREEN**: a style-neutral prompt + an enabled "crayon" card produced an unmistakable crayon drawing through the real transport; root causes were conversational phrasing + the `project_brief.enabled` master switch). Prior: [v0.27.1](LIVE_VERIFICATION_v0.27.1.md) (**v0.27.0 release follow-up fixes and documentation sync**). Prior: [v0.27.0](LIVE_VERIFICATION_v0.27.0.md) (**`[style]` block with named variants + prompt-aware resume — credit-free CLI verification**: real `movie run --dry-run` 3-way ledger proving resolved-style display, `skip (done)` on matching `style_hash`, and `re-run (style changed)` after a style edit; composition is local, wire path untouched, so no Veo credits spent — first credited styled run will confirm visually). Prior: [v0.26.0](LIVE_VERIFICATION_v0.26.0.md) (**image i2i by generated-image UUID proven live e2e GREEN** — the existing asset is *selected in place* by its media UUID, no duplicate upload, producing an i2i output that references it; plus generated-image `display_name` capture, credited @C1ph3r404). Prior: [v0.25.0](LIVE_VERIFICATION_v0.25.0.md) (**#237 remote-UUID i2v proven live e2e GREEN** — a real 8s 720×1280 interpolation from a generated image's UUID, after the picker-search attach was reworked to local upload; #240 home-`.env` matrix live; plus two silent-failure guards root-caused live: video-as-image download rejection and rejected-upload fail-loud). Prior: [v0.24.0](LIVE_VERIFICATION_v0.24.0.md) (--project parity across CLI + MCP — automated coverage; live gen auth-gated). Prior: [v0.23.0](LIVE_VERIFICATION_v0.23.0.md) (MCP generation wiring proven live end-to-end — tool→worker→real Flow REST→structured-error translation; final image-write blocked by an expired session, environmental. #222 macOS fix reporter-verified e2e on Apple Silicon). Prior: [v0.22.0](LIVE_VERIFICATION_v0.22.0.md) (Tools framework — automated/CI coverage complete; credit/key-gated live feature run is a pending owner gate, see the doc) · [v0.21.0](LIVE_VERIFICATION_v0.21.0.md) (MCP server over stdio + HTTP/SSE — credit-free protocol handshake; 4 tools / 2 prompts / 3 resources confirmed on stdout) · [v0.20.1](LIVE_VERIFICATION_v0.20.1.md) · [v0.20.0](LIVE_VERIFICATION_v0.20.0.md) · [v0.19.0](LIVE_VERIFICATION_v0.19.0.md) · [v0.18.0](LIVE_VERIFICATION_v0.18.0.md) · [v0.17.0](LIVE_VERIFICATION_v0.17.0.md) · [v0.16.0](LIVE_VERIFICATION_v0.16.0.md) · [v0.13.0](LIVE_VERIFICATION_v0.13.0.md) · [v0.12.0](LIVE_VERIFICATION_v0.12.0.md) · [v0.11.0](LIVE_VERIFICATION_v0.11.0.md) · [v0.10.0](LIVE_VERIFICATION_v0.10.0.md) · [v0.9.1](LIVE_VERIFICATION_v0.9.1.md) · [v0.9.0](LIVE_VERIFICATION_v0.9.0.md) · [v0.8.1](LIVE_VERIFICATION_v0.8.1.md) · [v0.7.0](LIVE_VERIFICATION_v0.7.0.md)
125
+ **"What was actually live-verified for the latest release?"** → latest: [LIVE_VERIFICATION_v0.32.0](LIVE_VERIFICATION_v0.32.0.md) (**#287 UUID i2v frames proven live e2e** — an in-project asset selected by media UUID in the frame-slot dialog [frame_ref_attached, startImage bound on the wire, ZERO upload events] produced a real 720×1280 interpolation, resolving the #237 negative prior; foreign UUID → exit 9 pre-generation with screenshot; **#288 duration fail-fast proven live** — exit 23 pre-submit saved a 10-credit generation, and the debug screenshot confirmed the duration control is ABSENT from the cohort's settings popover [locale hypothesis refuted]; upload-400 exit-27 repro deferred-with-reason — the original rejected JPEG no longer exists). Prior: [v0.31.0](LIVE_VERIFICATION_v0.31.0.md) (**#281 wrong-media defenses live-verified in BOTH directions, credit-free** — correct attribution downloads with real wire metadata [seed, 768×1376]; the incident-class lazy-render ambiguity reproduced live and hard-stopped with `MediaAttributionError` exit 26 naming every candidate UUID, no file written; **#282 two-UUID-ref i2i proven e2e** — both freshly generated portrait UUIDs picker-selected into one scene with both canonical identities visually transferred). Prior: [v0.30.0](LIVE_VERIFICATION_v0.30.0.md) (**agentic-cohort image path + both fixes live-verified credit-free** — native 768×1376 stills, i2i-chain + canonical-ref identity hold; the character-create `DataIntegrityError` and the `prefer_classic` WARNING were observed live then fixed [recorder idempotent + INFO log]; MCP video-param feature deferred-with-reason on Veo credits, per the stills-only goal). Prior: [v0.29.0](LIVE_VERIFICATION_v0.29.0.md) (**persistent `gflow instructions` CRUD proven live e2e GREEN, credit-free** — 11-command sequence on a fresh project: add incl. `--ref <image-UUID>` attach, list/enable/disable, master toggle both ways, TOML `apply` destructive full-sync with `enabled=false` honored, `rm` with server card-id preserved across mutations; movie brief-sync code-path-verified via the same primitives, deferred-with-reason on credits; MCP `gflow_instructions_*` tools are thin adapters over the live-verified primitives). Prior: [v0.28.0](LIVE_VERIFICATION_v0.28.0.md) (**agent instructions `-i` now steer agentic generation — crayon e2e GREEN**: a style-neutral prompt + an enabled "crayon" card produced an unmistakable crayon drawing through the real transport; root causes were conversational phrasing + the `project_brief.enabled` master switch). Prior: [v0.27.1](LIVE_VERIFICATION_v0.27.1.md) (**v0.27.0 release follow-up fixes and documentation sync**). Prior: [v0.27.0](LIVE_VERIFICATION_v0.27.0.md) (**`[style]` block with named variants + prompt-aware resume — credit-free CLI verification**: real `movie run --dry-run` 3-way ledger proving resolved-style display, `skip (done)` on matching `style_hash`, and `re-run (style changed)` after a style edit; composition is local, wire path untouched, so no Veo credits spent — first credited styled run will confirm visually). Prior: [v0.26.0](LIVE_VERIFICATION_v0.26.0.md) (**image i2i by generated-image UUID proven live e2e GREEN** — the existing asset is *selected in place* by its media UUID, no duplicate upload, producing an i2i output that references it; plus generated-image `display_name` capture, credited @C1ph3r404). Prior: [v0.25.0](LIVE_VERIFICATION_v0.25.0.md) (**#237 remote-UUID i2v proven live e2e GREEN** — a real 8s 720×1280 interpolation from a generated image's UUID, after the picker-search attach was reworked to local upload; #240 home-`.env` matrix live; plus two silent-failure guards root-caused live: video-as-image download rejection and rejected-upload fail-loud). Prior: [v0.24.0](LIVE_VERIFICATION_v0.24.0.md) (--project parity across CLI + MCP — automated coverage; live gen auth-gated). Prior: [v0.23.0](LIVE_VERIFICATION_v0.23.0.md) (MCP generation wiring proven live end-to-end — tool→worker→real Flow REST→structured-error translation; final image-write blocked by an expired session, environmental. #222 macOS fix reporter-verified e2e on Apple Silicon). Prior: [v0.22.0](LIVE_VERIFICATION_v0.22.0.md) (Tools framework — automated/CI coverage complete; credit/key-gated live feature run is a pending owner gate, see the doc) · [v0.21.0](LIVE_VERIFICATION_v0.21.0.md) (MCP server over stdio + HTTP/SSE — credit-free protocol handshake; 4 tools / 2 prompts / 3 resources confirmed on stdout) · [v0.20.1](LIVE_VERIFICATION_v0.20.1.md) · [v0.20.0](LIVE_VERIFICATION_v0.20.0.md) · [v0.19.0](LIVE_VERIFICATION_v0.19.0.md) · [v0.18.0](LIVE_VERIFICATION_v0.18.0.md) · [v0.17.0](LIVE_VERIFICATION_v0.17.0.md) · [v0.16.0](LIVE_VERIFICATION_v0.16.0.md) · [v0.13.0](LIVE_VERIFICATION_v0.13.0.md) · [v0.12.0](LIVE_VERIFICATION_v0.12.0.md) · [v0.11.0](LIVE_VERIFICATION_v0.11.0.md) · [v0.10.0](LIVE_VERIFICATION_v0.10.0.md) · [v0.9.1](LIVE_VERIFICATION_v0.9.1.md) · [v0.9.0](LIVE_VERIFICATION_v0.9.0.md) · [v0.8.1](LIVE_VERIFICATION_v0.8.1.md) · [v0.7.0](LIVE_VERIFICATION_v0.7.0.md)
126
126
  **"Where is the reverse-engineered wire protocol for a feature?"** → the `*_RECON.md` design docs: [CHARACTER_RECON](CHARACTER_RECON.md) (Flow character entity protocol), [IMAGE_UPSCALE_RECON](IMAGE_UPSCALE_RECON.md) (`/v1/flow/upsampleImage` wire). Naming convention: one `<FEATURE>_RECON.md` per reverse-engineered surface, kept as the durable spec after the feature ships.
127
127
  **"What was live-verified for the data layer (PR #58)?"** → [LIVE_VERIFICATION_data_layer](LIVE_VERIFICATION_data_layer.md) — 1 Imagen + 1 Veo credit on denon82, 6-layer ledger (file + magic + Pillow + DB rows + CLI round-trip + structlog)
128
128
  **"What was live-verified for the video-download feature (#29)?"** → [LIVE_VERIFICATION_video_download](LIVE_VERIFICATION_video_download.md)
@@ -0,0 +1,83 @@
1
+ # Live Verification — v0.31.0
2
+
3
+ **Date:** 2026-07-10 · **Profile:** `denon82` · **Project:** `f6caf027-ad68-49e3-aac9-ee32f1582bf3`
4
+ (the standing production project — deliberately asset-heavy, i.e. the exact environment of the
5
+ 2026-07-10 wrong-media incident this release fixes) · **Build:** develop @ `ecfb5ed`
6
+ (merge of PR #285) run via `uv run gflow` · **Model:** nano-pro · **Aspect:** 9:16 ·
7
+ **Credit cost:** 0 Veo credits (image generation only).
8
+
9
+ Features under verification (CHANGELOG `[Unreleased]` → 0.31.0):
10
+ 1. **#281 layer 1** — agentic ambiguity fail-fast + two-pass baseline settle (`MediaAttributionError`, exit 26)
11
+ 2. **#281 layers 2/3** — pre-download attribution guard + route-scoped collision escalation
12
+ 3. **#282** — UUID `--ref` picker: virtualised-grid scroll + search-state hygiene
13
+
14
+ ## Run 1 — t2i portrait (musician): correct attribution end-to-end ✅
15
+
16
+ `gflow image t2i "<musician portrait prompt>" --model nano-pro --aspect 9:16 --project f6caf027-… --out <dir>`
17
+
18
+ 5-layer ledger:
19
+ 1. **File count:** exactly 1 file produced: `98a404e7-766d-443c-9385-a16fdb37c799_1.jpg` (886,886 bytes; sha256 `e25e96be454f0215…`).
20
+ 2. **Magic bytes:** `ff d8 ff` (JPEG).
21
+ 3. **Dimensions:** 768×1376 (native 9:16, no crop).
22
+ 4. **Structlog invariants:** real wire metadata surfaced — `seed=648895`, `dimensions=768x1376`
23
+ (not the agentic scrape sentinels seed=0/0x0); **no** `data.persistence_failed_after_success`
24
+ warning (the 0.30.0 incident's tell); recorder wrote history cleanly.
25
+ 5. **User-confirmable artifact:** image visually inspected — weathered street musician, late 50s,
26
+ grey beard, black beanie, worn dark jacket, guitar, plain neutral background, front view.
27
+ Exactly the prompt; NOT a pre-existing project asset. (Under 0.30.0 in this same project, this
28
+ exact call once returned an old brand logo.)
29
+
30
+ ## Run 2 — t2i portrait (mentor), attempt 1: ambiguity fail-fast fires ✅ (negative-path proof)
31
+
32
+ Same command shape, mentor prompt. The generation hit the incident-class condition live: the
33
+ asset-heavy project lazy-rendered multiple prior assets after the baseline settle, and the run
34
+ **failed loudly instead of guessing**:
35
+
36
+ - `MediaAttributionError` raised naming **every** candidate UUID (the list included
37
+ `6a0b44d5-…` and `64fc2c31-…` — assets generated earlier that day, i.e. genuinely pre-existing
38
+ media that 0.30.0 would have been free to silently download) plus the remediation text
39
+ ("Re-run the generation; a dedicated project with fewer pre-existing assets avoids lazy-render
40
+ ambiguity (issue #281)").
41
+ - **No file was written** for this attempt (output dir unchanged).
42
+
43
+ This is the strongest possible live evidence for #281: the exact failure environment reproduced,
44
+ and the new behavior is a actionable hard stop, not a wrong artifact with exit 0.
45
+
46
+ ## Run 2 — t2i portrait (mentor), attempt 2: clean ✅
47
+
48
+ Retry of the same command: 1 file `dacdc6ee-2725-4e5c-b08f-c7143c36d9b6_1.jpg` (591,180 bytes;
49
+ sha256 `e82cc96b3bba60cf…`; JPEG magic `ff d8 ff`; 768×1376; real `seed=744814`; no persistence
50
+ warning). Visually inspected: elegant silver-haired man, 60s, tailored black suit, pocket square,
51
+ neutral background — exactly the prompt.
52
+
53
+ ## Run 3 — i2i with two UUID `--ref`s (#282 picker) ✅
54
+
55
+ `gflow image i2i "<street scene prompt>" --ref dacdc6ee-… --ref 98a404e7-… --model nano-pro
56
+ --aspect 9:16 --project f6caf027-… --out <dir>` — both refs are the freshly generated portrait
57
+ UUIDs from Runs 1–2, attached by picker selection (no local file passed). Under v0.30.0 this exact
58
+ call failed structurally: only the first UUID was picker-selectable (#282).
59
+
60
+ Two attempts noted for completeness: attempt 1 failed pre-submission with
61
+ `UiSelectorDriftError probe=mode_switch_trigger` whose debug screenshot was an entirely black
62
+ viewport — a page-that-never-rendered transient, not selector drift; zero generations spent.
63
+ Attempt 2 succeeded.
64
+
65
+ 5-layer ledger:
66
+ 1. **File count:** exactly 1 file: `d6f1927a-3eae-4626-bc90-9a6ea7637bab_1.jpg` (670,708 bytes;
67
+ sha256 `fd828df1a33e37c0…`).
68
+ 2. **Magic bytes:** `ff d8 ff` (JPEG).
69
+ 3. **Dimensions:** 768×1376 (native 9:16).
70
+ 4. **Structlog invariants:** real `seed=244712`; both refs attached (no
71
+ "could not be selected in the picker" error, no upload fallback); no persistence warning.
72
+ 5. **User-confirmable artifact:** visually inspected — BOTH canonical identities transferred:
73
+ the mentor is the same silver-haired man from Run 2's portrait (same face, suit, and paisley
74
+ pocket square), the musician the same man from Run 1's (same beanie, beard, work jacket).
75
+ Monochrome street scene with the iridescent coin accent confined to the guitar case. No
76
+ pre-existing project asset leaked into the frame.
77
+
78
+ ## Verdict
79
+
80
+ All three release features live-verified: #281's defense layers in both directions (correct
81
+ attribution succeeds with ground-truth metadata; incident-class ambiguity hard-stops with
82
+ actionable output and no file written), and #282's multi-UUID-ref picker selection end-to-end —
83
+ which simultaneously validates the canonical-reference identity workflow the fixes exist to serve.
@@ -0,0 +1,74 @@
1
+ # Live verification — v0.32.0 (2026-07-11)
2
+
3
+ Scope: the two user-facing changes of this release, exercised against live Flow
4
+ on the `denon82` profile (Classic strategy, Chrome, Windows 11; Flow renders in
5
+ Portuguese for this profile — `/fx/pt/` redirect). Credits spent: **1 image +
6
+ 1 video generation**; every failure-path check completed pre-submit at zero
7
+ credit cost.
8
+
9
+ ## 1. `gflow video i2v --initial-frame <UUID>` — in-project asset selection (#287, PR #290)
10
+
11
+ The declared-riskiest surface: the frame-slot dialog carried a negative prior
12
+ (#237's name-search never surfaced generated media there — see
13
+ [LIVE_VERIFICATION_v0.25.0](LIVE_VERIFICATION_v0.25.0.md)). The thumbnail-URL
14
+ tile match succeeds where name search failed.
15
+
16
+ Run: seed `gflow image t2i` (asset `0bbcdf05-19e0-43c3-bbeb-ba0ff7246e54`,
17
+ project `dd9e498c-22b1-4d73-a748-0bc0eac14c8b`), then
18
+ `gflow video i2v --initial-frame 0bbcdf05-… "slow cinematic push-in toward the
19
+ mug, steam rising gently" --project dd9e498c-… --profile denon82 --json`
20
+ (correlation `92b99c8c-5d69-4e00-905f-734f8eb6dadc`).
21
+
22
+ 5-layer ledger:
23
+
24
+ 1. **File count:** exactly 1 mp4 in `--out-dir` (`b61bcce6-baca-4934-b6e5-5ca84e10b49a.mp4`, 3,031,564 bytes).
25
+ 2. **Magic bytes:** `00 00 00 20 66 74 79 70 69 73 6f 6d` — valid `ftypisom` MP4 header.
26
+ 3. **Dimensions/shape:** ffprobe `720×1280`, duration `8.000000` s (Flow default — no `--duration` passed, correct).
27
+ 4. **Structlog invariants:**
28
+ - `ui_automation_video.frame_ref_attached {slot: Start, media_id: 0bbcdf05…}` — UUID picker selection in the frame-slot dialog;
29
+ - `ui_automation_video.generate_captured {url: …/video:batchAsyncGenerateVideoStartImage, image_inputs.startImage: "0bbcdf05"}` — the asset is bound in the actual wire request (no #125 T2V fallback);
30
+ - **zero `image_uploaded` events** in the whole run — no duplicate upload (the founding goal of #287);
31
+ - `poll_terminal {status: MEDIA_GENERATION_STATUS_SUCCESSFUL}` → `video_saved`.
32
+ 5. **User-confirmable artifact:** video `b61bcce6-…` in Flow project `dd9e498c-…` (denon82 account) — a genuine motion interpolation of the seeded red-mug still.
33
+
34
+ Negative check (free): a foreign UUID (`00000000-0000-4000-8000-000000000001`)
35
+ in the same project → **exit 9** (`TransportTimeoutError`) pre-generation, the
36
+ message naming slot + UUID + the `--project` hint, with
37
+ `debug_frame_ref_miss_start.png` captured (valid PNG).
38
+
39
+ Not verified this cycle: a live `uploadImage` HTTP-400 → exit 27
40
+ (`MediaUploadRejectedError`) repro — the original Flow-rejected JPEG from the
41
+ 2026-07-11 pilot no longer exists on disk (only thumbnails survive). The typed
42
+ raise is pinned by a unit test that drives the real `_upload_via_open_dialog`
43
+ listener with a 400 response (`tests/api/transports/test_ui_automation_video.py::TestUploadRejectionTypedError`).
44
+ The KNOWN_ISSUES entry on metadata-sensitive rejections tracks the live case.
45
+
46
+ ## 2. `--duration` fail-fast (#288, PR #289)
47
+
48
+ Run: `gflow video i2v <local file> "slow pan across the mug" --duration 4
49
+ --profile denon82 --json` (correlation `b8e66830-58bf-4928-9afe-1eecbbfcdb60`).
50
+
51
+ - `duration_tab` probe missed (reproducing the pilot's 3/3) and the run
52
+ **aborted pre-submit with exit 23** (`UiSelectorDriftError`) — the settings
53
+ popover showed "A geração vai usar 10 créditos", so the fail-fast saved that
54
+ spend instead of delivering a silent 8-second clip reported as success.
55
+ - `debug_no_duration_tab.png` captured (valid PNG, `89 50 4E 47` header) and
56
+ **answers the #288 investigation: the duration control is absent from this
57
+ cohort's Frames-submode settings popover** (rows rendered: Imagem/Vídeo →
58
+ Frames/Elementos → 9:16/16:9 → 1x/x2/x3/x4 → model dropdown; no duration
59
+ row). The council's locale hypothesis is refuted — the UI is Portuguese and
60
+ the sibling text-matched count tabs match fine.
61
+ - Happy-path caveat, recorded per the honesty rule: "duration tab found →
62
+ clicked" is unverifiable on this cohort because the control does not exist.
63
+ If a cohort still renders duration tabs, the pre-existing selector cascade
64
+ should match them unchanged; the fail-fast only fires on a miss.
65
+
66
+ ## Incidental live findings (logged on their issues)
67
+
68
+ - Project `f6caf027-…` opens in the full-page media-library UI (#174 shape,
69
+ "Agente" composer pill) where even `mode_switch_trigger` fails — fresh
70
+ projects still get the classic composer and work. Posted to #288/#174 trail.
71
+ - Error-path browser teardown can leave Chrome holding the profile dir
72
+ (subsequent runs die with `TargetClosedError` until the process is killed),
73
+ and `_capture_debug_screenshot` can report a screenshot path it never wrote
74
+ when capture fails. Both noted as #283-wave follow-ups.
@@ -46,7 +46,7 @@ The server registers three protocol surfaces:
46
46
 
47
47
  ### Tools (Executable actions)
48
48
  * `gflow_generate_image(prompt, model, aspect, count, seed, reference_images, tools, profile, project, instructions)`: Triggers text-to-image / image-to-image (Imagen / Nano Banana). `instructions` is an optional list of ephemeral agent-instruction strings (agentic cohort only). `reference_images` switches to i2i and accepts **either a local file path or a generated image's Flow media UUID**. A UUID reference is attached by **selecting the already-existing asset in Flow's reference picker — no duplicate copy is uploaded** (locating the tile by the media id in its thumbnail URL, and searching the recorded display name to surface it when needed); gflow falls back to uploading the asset's on-disk local file only when it can't be located in place (e.g. it lives in a different project's picker). `project` generates into an existing Flow project id (mirrors CLI `--project`) — pass the reference's project to keep it selectable in place.
49
- * `gflow_generate_video(prompt, mode, aspect, initial_frame, end_frame, reference_images, model, duration, count, tools, profile, project)`: Triggers vertical or landscape video generation (Veo). `mode` is `t2v`/`i2v`/`r2v`; `model` (`veo_lite`/`veo_fast`/`veo_quality`/`omni_flash`, aliases accepted), `duration` (seconds), and `count` mirror the CLI `gflow video` flags — an omitted `model` lets the transport apply its i2v veo-lite default (issue #125), and `omni_flash` is rejected for i2v-with-frames; `i2v` requires `initial_frame`, `r2v` requires `reference_images`; `project` generates into an existing Flow project id (mirrors CLI `--project`). `initial_frame`, `end_frame`, and `reference_images` each accept **either a local file path or the Flow image UUID of a generated asset** — pass a generated image's id straight in to chain image→video, and gflow attaches it for you (the UUID is resolved to the asset's already-on-disk local file and uploaded as the frame; no manual download/re-upload step). A UUID that isn't in your local asset catalog is rejected up front with a clear "Reference Not Found" error; a catalogued asset whose local file is no longer on disk gives a "Reference Not On Disk" error (re-generate it or pass a local path).
49
+ * `gflow_generate_video(prompt, mode, aspect, initial_frame, end_frame, reference_images, model, duration, count, tools, profile, project)`: Triggers vertical or landscape video generation (Veo). `mode` is `t2v`/`i2v`/`r2v`; `model` (`veo_lite`/`veo_fast`/`veo_quality`/`omni_flash`, aliases accepted), `duration` (seconds), and `count` mirror the CLI `gflow video` flags — an omitted `model` lets the transport apply its i2v veo-lite default (issue #125), and `omni_flash` is rejected for i2v-with-frames; `i2v` requires `initial_frame`, `r2v` requires `reference_images`; `project` generates into an existing Flow project id (mirrors CLI `--project`). `initial_frame`, `end_frame`, and `reference_images` each accept **either a local file path or the Flow image UUID of a generated asset** — pass a generated image's id straight in to chain image→video, and gflow attaches it for you (the UUID is resolved to the asset's already-on-disk local file and uploaded as the frame; no manual download/re-upload step). A UUID that isn't in your local asset catalog is rejected up front with a clear "Reference Not Found" error; a catalogued asset whose local file is no longer on disk gives a "Reference Not On Disk" error (re-generate it or pass a local path). Note the CLI's semantics diverge here (#287): `gflow video i2v --initial-frame <UUID>` selects the asset **in the project's media picker with no upload** and needs no local catalog entry — so the same UUID input can succeed on one surface and fail on the other.
50
50
  * `gflow_list_projects(profile, limit)`: Queries SQLite catalog for recent generation folders.
51
51
  * `gflow_list_characters(profile)`: Lists Flow Character entities (requires an active browser session).
52
52
  * `gflow_list_tools()`: Lists the prompt tools (name/title/description/category) accepted by the generate tools' `tools` param.
@@ -67,7 +67,7 @@ See [AUTHENTICATION § Commands](AUTHENTICATION.md#commands).
67
67
 
68
68
  ## `gflow image upload`
69
69
 
70
- Upload a local PNG/JPEG/WebP/GIF into a fresh Flow project and print the asset UUID + dimensions Flow inferred. The UUID is what later subcommands (`gflow image i2i --ref UUID`, `video i2v`) accept as an initial frame.
70
+ Upload a local PNG/JPEG/WebP/GIF into a fresh Flow project and print the asset UUID + dimensions Flow inferred. The UUID is what later subcommands (`gflow image i2i --ref UUID`, `video i2v`) accept as an initial frame. Note for `video i2v`: the UUID is selected from the generation project's media picker, and `upload` puts the asset in a *fresh scratch project* — so pass `--project <id>` of the project that holds the asset, or the picker lookup fails with exit 9 (#287).
71
71
 
72
72
  ```text
73
73
  gflow image upload PATH [OPTIONS]
@@ -460,9 +460,12 @@ gflow video t2v "a dog surfing" --tool creative-director:style=cinematic
460
460
  ## `gflow video i2v`
461
461
 
462
462
  Generate a video from an INITIAL frame (+ optional END frame) and a motion prompt.
463
- Each image is a local PNG/JPEG; it is bound into the editor's frame slot via the
464
- media dialog, then Flow fires `batchAsyncGenerateVideoStartImage` (initial only) or
465
- `…StartAndEndImage` (initial+end interpolation).
463
+ Each frame is a local PNG/JPEG **or the media UUID of an existing in-project asset**
464
+ (#287 — the asset is selected in place, no duplicate upload; pair with `--project`
465
+ so the UUID's project is the one being generated in). A local file is bound into
466
+ the editor's frame slot via the media dialog, then Flow fires
467
+ `batchAsyncGenerateVideoStartImage` (initial only) or `…StartAndEndImage`
468
+ (initial+end interpolation).
466
469
 
467
470
  ```text
468
471
  gflow video i2v --initial-frame INITIAL [--end-frame LAST] PROMPT [--model] [--duration] [--count] [--aspect] [...]
@@ -474,19 +477,28 @@ Arguments:
474
477
  PROMPT Motion prompt. [required]
475
478
 
476
479
  Options:
477
- --initial-frame PATH Initial frame to animate. Canonical form; replaces the positional IMAGE.
478
- --end-frame PATH Optional end frame — Flow interpolates initial frame -> end frame.
479
- --project ID Generate in this EXISTING Flow project instead of a
480
- scratch project (see "Sharing one project across calls").
480
+ --initial-frame PATH|UUID Initial frame to animate: local image path or in-project
481
+ asset media UUID. Canonical form; replaces the positional IMAGE.
482
+ --end-frame PATH|UUID Optional end frame — Flow interpolates initial frame -> end frame.
483
+ --project ID Generate in this EXISTING Flow project instead of a
484
+ scratch project (see "Sharing one project across calls").
481
485
  ```
482
486
 
483
487
  ```bash
484
488
  gflow video i2v --initial-frame ./hero.png "Slow camera arc, soft golden light"
485
489
  gflow video i2v --initial-frame ./first.png --end-frame ./last.png "morph between scenes" --model veo-quality
490
+ # Reference an existing in-project asset by media UUID (no re-upload, #287):
491
+ gflow video i2v --initial-frame d6f1927a-3eae-4626-bc90-9a6ea7637bab "pan left" --project f6caf027-...
486
492
  # Back-compat positional form:
487
493
  gflow video i2v ./hero.png "Slow camera arc, soft golden light"
488
494
  ```
489
495
 
496
+ Exit codes specific to this surface: **27** — Flow's upload endpoint rejected a
497
+ local frame file (`MediaUploadRejectedError`; try re-encoding, e.g.
498
+ `ffmpeg -i in.jpg -q:v 2 -map_metadata -1 out.jpg`, or reference the asset by
499
+ UUID instead); **9** — a frame UUID could not be located in the project's media
500
+ picker (`TransportTimeoutError`; wrong `--project` or foreign UUID).
501
+
490
502
  ## `gflow video r2v`
491
503
 
492
504
  Reference-to-video (Flow "ingredients"): condition a generation on reference
@@ -1212,7 +1224,7 @@ shell scripts can branch on the failure mode without parsing stderr.
1212
1224
  | `6` | `NetworkError` | Network failure persisted across 3 attempts | Check connectivity |
1213
1225
  | `7` | `WireFormatError` | Unexpected response shape — Flow API changed | File a bug (do NOT include captured tokens or signed URLs) |
1214
1226
  | `8` | `AuthMissingError` | Required auth credential is absent from profile | `gflow auth login --profile <name>` |
1215
- | `9` | `TransportTimeoutError` | Browser/API operation exceeded its timeout | Retry; raise the relevant timeout if needed |
1227
+ | `9` | `TransportTimeoutError` | Browser/API operation exceeded its timeout (incl. an i2v frame UUID not found in the media picker, #287) | Retry; raise the relevant timeout — or, for a frame-UUID miss, verify the UUID belongs to the `--project` passed |
1216
1228
  | `10` | `WafRejectionError` | Flow security layer rejected the request | Change prompt/request and retry |
1217
1229
  | `11` | `ConfigurationError` | Local configuration or browser mode is invalid | Fix the option/env var shown in the error |
1218
1230
  | `12` | `AuthLoginTimeoutError` | Browser sign-in was not completed in time | Re-run login or raise `GFLOW_CLI_AUTH_LOGIN_TIMEOUT` |
@@ -1228,6 +1240,9 @@ shell scripts can branch on the failure mode without parsing stderr.
1228
1240
  | `22` | `UpscaleUnavailableError` | 4K upscale is gated to Flow **Ultra** accounts (HTTP 403) | Use `--scale 2k`, or upgrade the Flow plan |
1229
1241
  | `23` | `UiSelectorDriftError` | A Flow editor control could not be located — Google changed the frontend (issue #183) | Update gflow-cli; file a bug with the probe name + debug screenshot from the error message |
1230
1242
  | `24` | `BrowserEngineUnavailableError` | `GFLOW_CLI_BROWSER_ENGINE=patchright` but the engine is not installed | `pip install 'gflow-cli[patchright]'`, or unset `GFLOW_CLI_BROWSER_ENGINE` |
1243
+ | `25` | `FlowAgentUiError` | The profile is on Flow's Agentic UI cohort and the classic media panel is unrecoverable for this operation | Use a Classic-cohort profile; see KNOWN_ISSUES on the agentic cohort |
1244
+ | `26` | `MediaAttributionError` | Generated media could not be reliably attributed to this request (issue #281) | Re-run; a dedicated project with fewer pre-existing assets avoids the ambiguity |
1245
+ | `27` | `MediaUploadRejectedError` | Flow's upload endpoint refused the input file (`uploadImage` 4xx, issue #287) | Re-encode the image (`ffmpeg -q:v 2 -map_metadata -1`), or reference the asset by its media UUID |
1231
1246
  | `130`| SIGINT | User-interrupted (Ctrl-C) | — |
1232
1247
 
1233
1248
  **Exit code 16 — data store / migration error.** Fires when:
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "gflow-cli"
3
- version = "0.30.0"
3
+ version = "0.32.0"
4
4
  description = "Unofficial CLI for Google Flow — drive Veo image-to-video generations from the terminal."
5
5
  readme = "README.md"
6
6
  license = { file = "LICENSE" }
@@ -106,7 +106,7 @@ async def _run(
106
106
  if full:
107
107
  await VideoGenerationMixin._select_video_aspect(page, Aspect.PORTRAIT) # noqa: SLF001
108
108
  await VideoGenerationMixin._set_output_count(page, 1) # noqa: SLF001
109
- await VideoGenerationMixin._select_video_duration(page, 8) # noqa: SLF001
109
+ await VideoGenerationMixin._select_video_duration(page, 8, out_dir=None) # noqa: SLF001
110
110
  await page.keyboard.press("Escape")
111
111
  await page.wait_for_timeout(600)
112
112
  await page.wait_for_timeout(800)
@@ -68,7 +68,7 @@ gflow image i2i "<prompt>" --ref PATH_OR_UUID [--ref ...] [...same as t2i]
68
68
 
69
69
  # Video generation (Veo 3.1)
70
70
  gflow video t2v "<prompt>" [--out-dir DIR] [--aspect ...] [--seed N]
71
- gflow video i2v --initial-frame <image> "<prompt>" [--out-dir DIR] [...same as t2v]
71
+ gflow video i2v --initial-frame <image|media-UUID> "<prompt>" [--out-dir DIR] [...same as t2v] # UUID = in-project asset, no re-upload (#287; pair with --project)
72
72
  gflow video batch <manifest.tsv> [--out-dir DIR]
73
73
  gflow video chain <manifest.jsonl> [--out-dir DIR] [--dry-run] \
74
74
  [--max-links N] [--resume-from N] # last-frame I2V chaining; veo models only
@@ -259,7 +259,7 @@ Documented errors agents commonly make — negative examples for the SkillOpt tr
259
259
  | `playwright install` or `playwright install --all` | `uvx --from gflow-cli playwright install chromium` (Chromium only, ~150 MB) |
260
260
  | Running two generations on the same `--profile` in parallel | Use different `--profile` names — Chromium refuses two persistent contexts on the same dir |
261
261
  | `GFLOW_CLI_HEADLESS=true` to fix reCAPTCHA failures | `GFLOW_CLI_HEADLESS=false` — headless mode *causes* bot-detection, not prevents it |
262
- | Calling `gflow image upload` again for an already-uploaded UUID | Pass the UUID directly to `--ref UUID` — no re-upload needed |
262
+ | Calling `gflow image upload` again for an already-uploaded UUID | Pass the UUID directly to `--ref UUID` (i2i) or `--initial-frame/--end-frame UUID` (i2v, with `--project`) — no re-upload needed |
263
263
  | `--model imagen` / `--model quality` / `--model high` | `--model image4` (Imagen 3.5), `--model nano-pro` (Gem Pix 2), `--model nano2` (Narwhal) |
264
264
  | Python: `client = FlowApiClient(...)` then method calls | Must use `async with FlowApiClient(...) as client:` — it's an async context manager |
265
265
  | Python: `from gflow_cli import FlowApiClient` | `from gflow_cli.api.client import FlowApiClient` |
@@ -1,3 +1,3 @@
1
1
  """gflow-cli — unofficial CLI for Google Flow."""
2
2
 
3
- __version__ = "0.30.0"
3
+ __version__ = "0.32.0"