gflow-cli 0.20.0__tar.gz → 0.20.1__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 (433) hide show
  1. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/.env.template +6 -0
  2. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/CHANGELOG.md +9 -1
  3. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/PKG-INFO +1 -1
  4. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/docs/CONFIGURATION.md +8 -0
  5. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/docs/INDEX.md +1 -1
  6. gflow_cli-0.20.1/docs/LIVE_VERIFICATION_v0.20.1.md +19 -0
  7. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/pyproject.toml +1 -1
  8. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/src/gflow_cli/__init__.py +1 -1
  9. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/src/gflow_cli/api/transports/drivers/factory.py +12 -0
  10. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/src/gflow_cli/api/transports/ui_automation.py +6 -2
  11. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/src/gflow_cli/config.py +10 -0
  12. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/api/transports/drivers/test_factory.py +38 -0
  13. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/api/transports/test_ui_automation.py +27 -0
  14. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/api/transports/test_ui_automation_batch.py +57 -0
  15. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/test_config.py +9 -0
  16. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/uv.lock +1 -1
  17. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/.claude/README.md +0 -0
  18. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/.claude/commands/gflow/active.md +0 -0
  19. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/.claude/commands/gflow/branch-review.md +0 -0
  20. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/.claude/commands/gflow/changelog.md +0 -0
  21. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/.claude/commands/gflow/check.md +0 -0
  22. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/.claude/commands/gflow/doc-review.md +0 -0
  23. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/.claude/commands/gflow/known-issues.md +0 -0
  24. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/.claude/commands/gflow/next.md +0 -0
  25. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/.claude/commands/gflow/plan.md +0 -0
  26. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/.claude/commands/gflow/pr-council-review.md +0 -0
  27. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/.claude/commands/gflow/predict.md +0 -0
  28. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/.claude/commands/gflow/release.md +0 -0
  29. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/.claude/commands/gflow/scenario.md +0 -0
  30. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/.claude/commands/gflow/status.md +0 -0
  31. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/.gitattributes +0 -0
  32. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/.github/CODEOWNERS +0 -0
  33. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  34. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/.github/copilot-instructions.md +0 -0
  35. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/.github/dependabot.yml +0 -0
  36. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/.github/workflows/ci.yml +0 -0
  37. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/.github/workflows/external-pr-triage.yml +0 -0
  38. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/.github/workflows/governance-advisory.yml +0 -0
  39. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/.github/workflows/governance-benchmark.yml +0 -0
  40. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/.github/workflows/release.yml +0 -0
  41. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/.gitignore +0 -0
  42. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/.gitleaks.toml +0 -0
  43. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/.pre-commit-config.yaml +0 -0
  44. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/.secrets.baseline +0 -0
  45. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/AGENTS.md +0 -0
  46. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/CLAUDE.md +0 -0
  47. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/CONFIGURATION.md +0 -0
  48. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/CONTRIBUTING.md +0 -0
  49. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/DISCLAIMER.md +0 -0
  50. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/GEMINI.md +0 -0
  51. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/KNOWN_ISSUES.md +0 -0
  52. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/LICENSE +0 -0
  53. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/PLAN.md +0 -0
  54. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/README.md +0 -0
  55. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/RELEASE.md +0 -0
  56. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/ROADMAP.md +0 -0
  57. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/conftest.py +0 -0
  58. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/docker-compose.yml +0 -0
  59. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/docs/AGENT_GUIDE.md +0 -0
  60. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/docs/AGENT_UI_E2E.md +0 -0
  61. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/docs/AGENT_UI_RECON.md +0 -0
  62. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/docs/ARCHITECTURE.md +0 -0
  63. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/docs/AUTHENTICATION.md +0 -0
  64. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/docs/CHARACTER.md +0 -0
  65. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/docs/CHARACTER_RECON.md +0 -0
  66. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/docs/DATA_LAYER.md +0 -0
  67. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/docs/DEBUGGING.md +0 -0
  68. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/docs/DEMOS.md +0 -0
  69. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/docs/DEVELOPMENT.md +0 -0
  70. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/docs/E2E_TESTING.md +0 -0
  71. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/docs/EXTERNAL_STORAGE.md +0 -0
  72. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/docs/GITHUB.md +0 -0
  73. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/docs/GOVERNANCE_BENCHMARK.md +0 -0
  74. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/docs/IMAGE_UPSCALE_RECON.md +0 -0
  75. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/docs/LIVE_VERIFICATION_data_layer.md +0 -0
  76. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/docs/LIVE_VERIFICATION_image_batch.md +0 -0
  77. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/docs/LIVE_VERIFICATION_v0.10.0.md +0 -0
  78. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/docs/LIVE_VERIFICATION_v0.11.0.md +0 -0
  79. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/docs/LIVE_VERIFICATION_v0.12.0.md +0 -0
  80. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/docs/LIVE_VERIFICATION_v0.13.0.md +0 -0
  81. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/docs/LIVE_VERIFICATION_v0.16.0.md +0 -0
  82. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/docs/LIVE_VERIFICATION_v0.17.0.md +0 -0
  83. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/docs/LIVE_VERIFICATION_v0.18.0.md +0 -0
  84. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/docs/LIVE_VERIFICATION_v0.19.0.md +0 -0
  85. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/docs/LIVE_VERIFICATION_v0.20.0.md +0 -0
  86. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/docs/LIVE_VERIFICATION_v0.7.0.md +0 -0
  87. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/docs/LIVE_VERIFICATION_v0.8.1.md +0 -0
  88. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/docs/LIVE_VERIFICATION_v0.9.0.md +0 -0
  89. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/docs/LIVE_VERIFICATION_v0.9.1.md +0 -0
  90. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/docs/LIVE_VERIFICATION_video_download.md +0 -0
  91. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/docs/MOVIE.md +0 -0
  92. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/docs/PROJECT_STATUS.md +0 -0
  93. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/docs/SECURITY.md +0 -0
  94. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/docs/USAGE.md +0 -0
  95. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/docs/USER_GUIDE.md +0 -0
  96. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/docs/assets/demo-split-pf.gif +0 -0
  97. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/docs/assets/example-run.gif +0 -0
  98. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/docs/schemas/movie-handoff.schema.json +0 -0
  99. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/docs/superpowers/plans/2026-06-12-issue-174-library-ui-attach/PLAN.md +0 -0
  100. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/examples/README.md +0 -0
  101. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/examples/batch_from_config.py +0 -0
  102. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/examples/multi_prompt_t2i.py +0 -0
  103. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/examples/sample_config.json +0 -0
  104. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/examples/sample_prompts.txt +0 -0
  105. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/examples/single_image_t2i.py +0 -0
  106. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/examples/workflow_chain.py +0 -0
  107. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/llms.txt +0 -0
  108. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/samples/README.md +0 -0
  109. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/samples/captured/01_upload_image.json +0 -0
  110. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/samples/captured/02_batchAsyncGenerateVideoText.json +0 -0
  111. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/samples/captured/03_batchCheckAsyncVideoGenerationStatus.json +0 -0
  112. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/samples/captured/04_archive_workflow.json +0 -0
  113. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/samples/captured/05_createProject.json +0 -0
  114. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/samples/captured/06_batchGenerateImages.json +0 -0
  115. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/samples/captured/07_batchGenerateImages_seeded.json +0 -0
  116. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/samples/captured/08_batchAsyncGenerateVideoStartAndEndImage.json +0 -0
  117. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/samples/captured/09_batchAsyncGenerateVideoReferenceImages.json +0 -0
  118. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/samples/captured/10_batchCheckAsyncVideoGenerationStatus_successful.json +0 -0
  119. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/samples/captured/11_batchCheckAsyncVideoGenerationStatus_failed.json +0 -0
  120. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/samples/captured/12_create_scene.json +0 -0
  121. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/samples/captured/13_sceneWorkflows_update.json +0 -0
  122. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/samples/captured/14_get_scene_workflows.json +0 -0
  123. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/samples/captured/15_commit_flowWorkflow.json +0 -0
  124. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/scripts/ci/check_doc_links.py +0 -0
  125. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/scripts/ci/check_materiality.py +0 -0
  126. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/scripts/ci/check_repo_hygiene.py +0 -0
  127. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/scripts/debug_editor.py +0 -0
  128. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/scripts/debug_gen_settings.py +0 -0
  129. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/scripts/debug_settings.py +0 -0
  130. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/scripts/dev/_recording_client.py +0 -0
  131. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/scripts/dev/_spike_common.py +0 -0
  132. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/scripts/dev/active_plan.py +0 -0
  133. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/scripts/dev/analyze_agent_ui_capture.py +0 -0
  134. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/scripts/dev/capture_i2v_frame_slots_dom.py +0 -0
  135. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/scripts/dev/capture_i2v_intercept_submit.py +0 -0
  136. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/scripts/dev/capture_i2v_model_select_repro.py +0 -0
  137. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/scripts/dev/capture_i2v_post_bind_state.py +0 -0
  138. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/scripts/dev/capture_image_add_media_dom.py +0 -0
  139. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/scripts/dev/capture_locale_invariants.py +0 -0
  140. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/scripts/dev/cdp_drive_and_probe.py +0 -0
  141. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/scripts/dev/character_create_spike.py +0 -0
  142. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/scripts/dev/character_create_spike_v2.py +0 -0
  143. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/scripts/dev/dump_character_selectors.js +0 -0
  144. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/scripts/dev/make_project.py +0 -0
  145. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/scripts/dev/materiality_backtest.py +0 -0
  146. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/scripts/dev/monitor_pr_38.py +0 -0
  147. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/scripts/dev/patch_character.py +0 -0
  148. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/scripts/dev/record_flow_capture.py +0 -0
  149. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/scripts/dev/skillopt/README.md +0 -0
  150. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/scripts/dev/skillopt/harness.py +0 -0
  151. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/scripts/dev/skillopt/tasks.json +0 -0
  152. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/scripts/dev/spike_char_editor_dom.py +0 -0
  153. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/scripts/dev/spike_char_gen_capture.py +0 -0
  154. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/scripts/dev/spike_image_upscale_capture.py +0 -0
  155. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/scripts/dev/spike_image_upscale_drive.py +0 -0
  156. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/scripts/dev/spike_image_upscale_recaptcha_action.py +0 -0
  157. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/scripts/dev/spike_image_upscale_rest_probe.py +0 -0
  158. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/scripts/dev/spike_issue170_picker_locale_recon.py +0 -0
  159. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/scripts/dev/spike_issue174_library_ui_recon.py +0 -0
  160. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/scripts/dev/spike_movie_attach_payload.py +0 -0
  161. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/scripts/dev/spike_movie_entity_recon.py +0 -0
  162. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/scripts/dev/spike_movie_gen_capture.py +0 -0
  163. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/scripts/dev/spike_movie_picker_select.py +0 -0
  164. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/scripts/dev/spike_movie_voice_list.py +0 -0
  165. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/scripts/dev/spike_patch_entity.py +0 -0
  166. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/scripts/dev/spike_patchright.py +0 -0
  167. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/scripts/diag/README.md +0 -0
  168. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/scripts/diag/capture_flow_traffic.py +0 -0
  169. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/scripts/diag/memory_profile.py +0 -0
  170. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/scripts/diag/recaptcha_mint.py +0 -0
  171. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/scripts/e2e/agentic_image_e2e.ps1 +0 -0
  172. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/scripts/e2e/capture_agent_toggle.py +0 -0
  173. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/scripts/record_demo.ps1 +0 -0
  174. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/scripts/smoke_image.py +0 -0
  175. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/scripts/smoke_real_chrome_image.py +0 -0
  176. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/scripts/smoke_video_editor.py +0 -0
  177. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/scripts/smoke_worker_style.py +0 -0
  178. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/scripts/verify_chrome_auth_viability.py +0 -0
  179. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/skills/README.md +0 -0
  180. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/skills/gflow-cli/SKILL.md +0 -0
  181. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/skills/plan/SKILL.md +0 -0
  182. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/skills/pr-council-review/SKILL.md +0 -0
  183. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/skills/predict/SKILL.md +0 -0
  184. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/skills/scenario/SKILL.md +0 -0
  185. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/skills/status/SKILL.md +0 -0
  186. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/sonar-project.properties +0 -0
  187. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/src/gflow_cli/__main__.py +0 -0
  188. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/src/gflow_cli/_cli_helpers.py +0 -0
  189. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/src/gflow_cli/api/__init__.py +0 -0
  190. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/src/gflow_cli/api/_engine.py +0 -0
  191. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/src/gflow_cli/api/_retry.py +0 -0
  192. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/src/gflow_cli/api/_sapisidhash.py +0 -0
  193. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/src/gflow_cli/api/character.py +0 -0
  194. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/src/gflow_cli/api/client.py +0 -0
  195. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/src/gflow_cli/api/dto.py +0 -0
  196. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/src/gflow_cli/api/image.py +0 -0
  197. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/src/gflow_cli/api/image_upscale.py +0 -0
  198. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/src/gflow_cli/api/recaptcha.py +0 -0
  199. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/src/gflow_cli/api/routes.py +0 -0
  200. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/src/gflow_cli/api/scene.py +0 -0
  201. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/src/gflow_cli/api/transports/__init__.py +0 -0
  202. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/src/gflow_cli/api/transports/_common.py +0 -0
  203. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/src/gflow_cli/api/transports/_fingerprint.py +0 -0
  204. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/src/gflow_cli/api/transports/base.py +0 -0
  205. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/src/gflow_cli/api/transports/drivers/__init__.py +0 -0
  206. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/src/gflow_cli/api/transports/drivers/agentic.py +0 -0
  207. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/src/gflow_cli/api/transports/drivers/base.py +0 -0
  208. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/src/gflow_cli/api/transports/drivers/classic.py +0 -0
  209. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/src/gflow_cli/api/transports/experimental/__init__.py +0 -0
  210. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/src/gflow_cli/api/transports/experimental/bearer.py +0 -0
  211. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/src/gflow_cli/api/transports/experimental/evaluate_fetch.py +0 -0
  212. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/src/gflow_cli/api/transports/experimental/sapisidhash.py +0 -0
  213. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/src/gflow_cli/api/transports/ui_automation_video.py +0 -0
  214. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/src/gflow_cli/api/video.py +0 -0
  215. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/src/gflow_cli/auth/__init__.py +0 -0
  216. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/src/gflow_cli/auth/base.py +0 -0
  217. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/src/gflow_cli/auth/cookies.py +0 -0
  218. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/src/gflow_cli/auth/factory.py +0 -0
  219. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/src/gflow_cli/auth/internal_chromium.py +0 -0
  220. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/src/gflow_cli/auth/real_chrome.py +0 -0
  221. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/src/gflow_cli/auth/strategies.py +0 -0
  222. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/src/gflow_cli/auth/verification.py +0 -0
  223. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/src/gflow_cli/browser_manager.py +0 -0
  224. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/src/gflow_cli/chain.py +0 -0
  225. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/src/gflow_cli/chain_manifest.py +0 -0
  226. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/src/gflow_cli/cli.py +0 -0
  227. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/src/gflow_cli/cli_character.py +0 -0
  228. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/src/gflow_cli/cli_data.py +0 -0
  229. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/src/gflow_cli/cli_image.py +0 -0
  230. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/src/gflow_cli/cli_models.py +0 -0
  231. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/src/gflow_cli/cli_movie.py +0 -0
  232. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/src/gflow_cli/cli_run.py +0 -0
  233. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/src/gflow_cli/cli_scene.py +0 -0
  234. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/src/gflow_cli/cli_video.py +0 -0
  235. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/src/gflow_cli/composition.py +0 -0
  236. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/src/gflow_cli/data/__init__.py +0 -0
  237. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/src/gflow_cli/data/chain_repo.py +0 -0
  238. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/src/gflow_cli/data/migrations/0001_initial.sql +0 -0
  239. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/src/gflow_cli/data/migrations/0002_add_cloud_storage.sql +0 -0
  240. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/src/gflow_cli/data/migrations/0003_add_scene_tables.sql +0 -0
  241. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/src/gflow_cli/data/migrations/0004_add_scene_output_path.sql +0 -0
  242. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/src/gflow_cli/data/migrations/0005_add_chain_links.sql +0 -0
  243. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/src/gflow_cli/data/migrations/0006_add_operations_metadata.sql +0 -0
  244. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/src/gflow_cli/data/migrations/__init__.py +0 -0
  245. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/src/gflow_cli/data/models.py +0 -0
  246. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/src/gflow_cli/data/queries.py +0 -0
  247. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/src/gflow_cli/data/recorder.py +0 -0
  248. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/src/gflow_cli/data/redaction.py +0 -0
  249. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/src/gflow_cli/data/repository.py +0 -0
  250. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/src/gflow_cli/data/store.py +0 -0
  251. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/src/gflow_cli/errors.py +0 -0
  252. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/src/gflow_cli/exceptions.py +0 -0
  253. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/src/gflow_cli/image_batch.py +0 -0
  254. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/src/gflow_cli/json_output.py +0 -0
  255. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/src/gflow_cli/manifest.py +0 -0
  256. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/src/gflow_cli/media.py +0 -0
  257. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/src/gflow_cli/movie_manifest.py +0 -0
  258. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/src/gflow_cli/observability.py +0 -0
  259. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/src/gflow_cli/paths.py +0 -0
  260. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/src/gflow_cli/profile_store.py +0 -0
  261. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/src/gflow_cli/services/__init__.py +0 -0
  262. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/src/gflow_cli/services/character_create.py +0 -0
  263. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/src/gflow_cli/storage.py +0 -0
  264. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tasks/lessons.md +0 -0
  265. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/test_assets/sample_batch.json +0 -0
  266. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/test_assets/sample_batch.tsv +0 -0
  267. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/test_assets/sample_batch_invalid.tsv +0 -0
  268. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/__init__.py +0 -0
  269. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/api/__init__.py +0 -0
  270. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/api/fixtures/character_gen_response.json +0 -0
  271. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/api/fixtures/patch_entity_response.json +0 -0
  272. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/api/test_aisandbox_auth_error.py +0 -0
  273. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/api/test_aisandbox_auth_headers.py +0 -0
  274. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/api/test_bearer_redaction.py +0 -0
  275. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/api/test_character.py +0 -0
  276. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/api/test_client.py +0 -0
  277. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/api/test_client_character.py +0 -0
  278. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/api/test_client_delete_characters.py +0 -0
  279. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/api/test_client_generate_character.py +0 -0
  280. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/api/test_client_image.py +0 -0
  281. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/api/test_client_launch_kwargs.py +0 -0
  282. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/api/test_client_patch_entity.py +0 -0
  283. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/api/test_client_scene.py +0 -0
  284. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/api/test_client_upscale.py +0 -0
  285. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/api/test_concurrency.py +0 -0
  286. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/api/test_dto.py +0 -0
  287. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/api/test_engine.py +0 -0
  288. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/api/test_image.py +0 -0
  289. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/api/test_image_dto.py +0 -0
  290. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/api/test_image_upscale.py +0 -0
  291. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/api/test_post_json_aisandbox_auth.py +0 -0
  292. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/api/test_recaptcha.py +0 -0
  293. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/api/test_retry.py +0 -0
  294. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/api/test_routes.py +0 -0
  295. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/api/test_routes_character.py +0 -0
  296. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/api/test_routes_scene.py +0 -0
  297. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/api/test_sapisidhash_helper.py +0 -0
  298. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/api/test_scene_models.py +0 -0
  299. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/api/test_video.py +0 -0
  300. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/api/test_video_request.py +0 -0
  301. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/api/transports/__init__.py +0 -0
  302. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/api/transports/conftest.py +0 -0
  303. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/api/transports/drivers/__init__.py +0 -0
  304. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/api/transports/drivers/test_agentic.py +0 -0
  305. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/api/transports/test_base.py +0 -0
  306. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/api/transports/test_bearer.py +0 -0
  307. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/api/transports/test_common.py +0 -0
  308. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/api/transports/test_evaluate_fetch.py +0 -0
  309. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/api/transports/test_factory.py +0 -0
  310. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/api/transports/test_fingerprint.py +0 -0
  311. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/api/transports/test_sapisidhash.py +0 -0
  312. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/api/transports/test_transport_timeout.py +0 -0
  313. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/api/transports/test_ui_automation_image_mode.py +0 -0
  314. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/api/transports/test_ui_automation_video.py +0 -0
  315. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/api/transports/test_ui_character_editor.py +0 -0
  316. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/auth/strategies/test_factory.py +0 -0
  317. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/auth/strategies/test_strategies.py +0 -0
  318. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/auth/test_verification.py +0 -0
  319. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/cli/__init__.py +0 -0
  320. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/cli/test_cli_auth_list.py +0 -0
  321. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/cli/test_cli_character.py +0 -0
  322. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/cli/test_cli_character_create.py +0 -0
  323. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/cli/test_cli_data.py +0 -0
  324. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/cli/test_cli_image.py +0 -0
  325. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/cli/test_cli_image_seed_removed.py +0 -0
  326. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/cli/test_cli_image_selector_drift.py +0 -0
  327. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/cli/test_cli_image_upscale.py +0 -0
  328. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/cli/test_cli_models.py +0 -0
  329. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/cli/test_cli_movie.py +0 -0
  330. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/cli/test_cli_run.py +0 -0
  331. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/cli/test_cli_scene.py +0 -0
  332. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/cli/test_cli_video.py +0 -0
  333. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/cli/test_cli_video_chain.py +0 -0
  334. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/cli/test_error_handling.py +0 -0
  335. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/cli/test_helpers.py +0 -0
  336. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/cli/test_movie_manifest.py +0 -0
  337. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/cli/test_settings_validation.py +0 -0
  338. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/cli/test_t2i_multi_prompt.py +0 -0
  339. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/composition/test_character.py +0 -0
  340. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/composition/test_compose_prompt.py +0 -0
  341. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/composition/test_handoff.py +0 -0
  342. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/conftest.py +0 -0
  343. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/data/__init__.py +0 -0
  344. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/data/test_chain_repo.py +0 -0
  345. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/data/test_find_incomplete_character.py +0 -0
  346. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/data/test_models.py +0 -0
  347. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/data/test_packaging.py +0 -0
  348. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/data/test_recorder.py +0 -0
  349. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/data/test_recorder_character.py +0 -0
  350. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/data/test_redaction.py +0 -0
  351. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/data/test_repository.py +0 -0
  352. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/data/test_scene_persistence.py +0 -0
  353. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/data/test_settings_and_errors.py +0 -0
  354. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/data/test_store_migrations.py +0 -0
  355. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/dev/test_record_flow_capture.py +0 -0
  356. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/dev/test_recording_client.py +0 -0
  357. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/e2e/__init__.py +0 -0
  358. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/e2e/conftest.py +0 -0
  359. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/e2e/test_aisandbox_auth_live.py +0 -0
  360. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/e2e/test_auth_verification_e2e.py +0 -0
  361. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/e2e/test_chain_e2e.py +0 -0
  362. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/e2e/test_character_create_e2e.py +0 -0
  363. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/e2e/test_data_layer_e2e.py +0 -0
  364. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/e2e/test_i2v_flags_e2e.py +0 -0
  365. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/e2e/test_image_batch_e2e.py +0 -0
  366. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/e2e/test_image_i2i_ref_cap_e2e.py +0 -0
  367. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/e2e/test_json_output_e2e.py +0 -0
  368. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/e2e/test_locale_selectors_e2e.py +0 -0
  369. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/e2e/test_scene_compose_live.py +0 -0
  370. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/e2e/test_transports_e2e.py +0 -0
  371. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/e2e/test_video_r2v_ref_cap_e2e.py +0 -0
  372. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/e2e/test_video_t2v_e2e.py +0 -0
  373. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/features/__init__.py +0 -0
  374. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/features/auth.feature +0 -0
  375. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/features/auth_login.feature +0 -0
  376. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/features/character_create.feature +0 -0
  377. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/features/character_read.feature +0 -0
  378. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/features/conftest.py +0 -0
  379. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/features/image.feature +0 -0
  380. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/features/image_upscale.feature +0 -0
  381. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/features/locale_picker_include.feature +0 -0
  382. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/features/test_auth_login_steps.py +0 -0
  383. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/features/test_auth_steps.py +0 -0
  384. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/features/test_character_create_steps.py +0 -0
  385. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/features/test_character_read_steps.py +0 -0
  386. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/features/test_image_steps.py +0 -0
  387. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/features/test_image_upscale_steps.py +0 -0
  388. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/features/test_locale_picker_include_steps.py +0 -0
  389. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/features/test_step_collision_guard.py +0 -0
  390. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/features/test_video_agent_ui_steps.py +0 -0
  391. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/features/test_video_chain_steps.py +0 -0
  392. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/features/video_agent_ui.feature +0 -0
  393. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/features/video_chain.feature +0 -0
  394. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/fixtures/__init__.py +0 -0
  395. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/fixtures/seeded_catalog.py +0 -0
  396. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/image_batch/__init__.py +0 -0
  397. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/image_batch/test_image_manifest.py +0 -0
  398. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/image_batch/test_observability_events.py +0 -0
  399. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/integration/__init__.py +0 -0
  400. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/integration/conftest.py +0 -0
  401. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/integration/constants.py +0 -0
  402. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/integration/test_storage_gcs.py +0 -0
  403. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/integration/test_storage_s3.py +0 -0
  404. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/scripts/test_analyze_agent_ui_capture.py +0 -0
  405. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/scripts/test_capture_locale_invariants.py +0 -0
  406. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/scripts/test_check_materiality.py +0 -0
  407. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/scripts/test_check_repo_hygiene.py +0 -0
  408. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/scripts/test_materiality_backtest.py +0 -0
  409. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/services/__init__.py +0 -0
  410. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/services/test_character_create_redaction.py +0 -0
  411. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/services/test_character_create_saga.py +0 -0
  412. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/services/test_character_gen_no_direct_post.py +0 -0
  413. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/smoke/__init__.py +0 -0
  414. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/smoke/test_profile_account_smoke.py +0 -0
  415. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/smoke/test_real_flow.py +0 -0
  416. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/test_auth.py +0 -0
  417. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/test_browser_manager.py +0 -0
  418. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/test_chain.py +0 -0
  419. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/test_chain_manifest.py +0 -0
  420. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/test_cli_data.py +0 -0
  421. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/test_conftest_isolation.py +0 -0
  422. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/test_data_queries.py +0 -0
  423. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/test_documentation_gate.py +0 -0
  424. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/test_errors.py +0 -0
  425. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/test_errors_403.py +0 -0
  426. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/test_json_output.py +0 -0
  427. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/test_manifest.py +0 -0
  428. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/test_marker_registry.py +0 -0
  429. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/test_media.py +0 -0
  430. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/test_observability.py +0 -0
  431. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/test_paths.py +0 -0
  432. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/test_profile_store.py +0 -0
  433. {gflow_cli-0.20.0 → gflow_cli-0.20.1}/tests/test_smoke.py +0 -0
@@ -115,6 +115,12 @@
115
115
  # `patchright install chromium`. Unset to revert to the default playwright engine.
116
116
  # GFLOW_CLI_BROWSER_ENGINE=playwright
117
117
 
118
+ # Try to force the Classic Flow UI mode for image generation by clicking the Agent toggle pill
119
+ # if the page mounts in Agentic mode. This ensures deterministic aspect ratio controls.
120
+ # If the page cannot be switched back to Classic, falls back to Agentic mode.
121
+ # GFLOW_CLI_PREFER_CLASSIC=false
122
+
123
+
118
124
  # BCP-47 locale tag passed to Playwright's launch `locale=` parameter
119
125
  # (controls Accept-Language only — Chrome's UI language is forced to
120
126
  # en-US via the `--lang=en-US` launch arg regardless of this setting, so
@@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.20.1] — 2026-06-16
11
+
12
+ ### Fixed
13
+
14
+ - **Aspect ratio overrides in Agentic & Classic cohorts** ([#193](https://github.com/ffroliva/gflow-cli/issues/193)): Fixed a bug where aspect ratio settings were ignored under the pluggable `FlowUiDriver` strategies (both single and batch image generation paths).
15
+ - **`GFLOW_CLI_PREFER_CLASSIC`** (or `prefer_classic` setting): Added a configuration setting to force the classic UI driver, allowing users to bypass the Agentic UI cohort if preferred.
16
+
10
17
  ## [0.20.0] — 2026-06-15
11
18
 
12
19
  ### Added
@@ -1558,7 +1565,8 @@ shell-script template that branches on these codes.
1558
1565
 
1559
1566
  First skeleton. Not functional end-to-end yet.
1560
1567
 
1561
- [Unreleased]: https://github.com/ffroliva/gflow-cli/compare/v0.20.0...HEAD
1568
+ [Unreleased]: https://github.com/ffroliva/gflow-cli/compare/v0.20.1...HEAD
1569
+ [0.20.1]: https://github.com/ffroliva/gflow-cli/compare/v0.20.0...v0.20.1
1562
1570
  [0.20.0]: https://github.com/ffroliva/gflow-cli/compare/v0.19.0...v0.20.0
1563
1571
  [0.19.0]: https://github.com/ffroliva/gflow-cli/compare/v0.18.0...v0.19.0
1564
1572
  [0.18.0]: https://github.com/ffroliva/gflow-cli/compare/v0.17.0...v0.18.0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gflow-cli
3
- Version: 0.20.0
3
+ Version: 0.20.1
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
@@ -200,6 +200,14 @@ GFLOW_CLI_HISTORY_PROMPTS=redacted gflow image t2i "confidential brief"
200
200
  **Reverting:** unset the variable (or set `playwright`) — the default path is byte-identical to a build without this feature, with no profile migration.
201
201
  **Security note:** the `patchright` extra ships a *patched Chromium driver* that handles your live Google session cookies; it is exact-pinned and treated as a security-review-required dependency. See [SECURITY.md § Dependencies](SECURITY.md).
202
202
 
203
+ ### `GFLOW_CLI_PREFER_CLASSIC`
204
+
205
+ **What:** Try to force the Classic Flow UI mode for image generation by clicking the Agent toggle pill if the page mounts in Agentic mode.
206
+ **Values:** `true` | `false`
207
+ **Default:** `false`
208
+ **Why use it:** The Agentic UI cohort (conversational chat) treats requested aspect ratios as a soft prompt hint, which can result in inconsistent aspect ratios (e.g. producing landscape when portrait 9:16 was requested). Exposing this setting allows callers to opt into switching the UI back to Classic mode where aspect ratios are enforced deterministically (via hard Flow crop controls).
209
+ **Fallback:** If the page cannot be switched back to Classic (e.g., in a forced A/B cohort where the toggle is not available), the driver gracefully falls back to Agentic mode rather than blocking execution.
210
+
203
211
  ### `GFLOW_CLI_LOCALE`
204
212
 
205
213
  **What:** BCP-47 locale tag passed to Playwright's `launch_persistent_context(locale=...)` — controls the `Accept-Language` HTTP header only.
@@ -112,7 +112,7 @@ Slash commands for Claude Code, stored in `.claude/commands/gflow/`. All prefixe
112
112
  **"A gflow command hangs / fails — where do I start?"** → [DEBUGGING § Quick reference](DEBUGGING.md#quick-reference)
113
113
  **"Flow's UI broke a selector — how do I diagnose it?"** → [DEBUGGING § Inspecting Flow's live UI](DEBUGGING.md#inspecting-flows-live-ui)
114
114
  **"What does each `ui_automation.*` log event mean?"** → [DEBUGGING § Listener & HTTP-layer debugging](DEBUGGING.md#listener--http-layer-debugging)
115
- **"What was actually live-verified for the latest release?"** → latest: [LIVE_VERIFICATION_v0.20.0](LIVE_VERIFICATION_v0.20.0.md) (Agentic UI image generation on `denon82`: classic `image t2i` + `video t2v` unaffected, and forced-agentic `image t2i` count 1 & count 3 with **live dedup-by-UUID** under `GFLOW_CLI_FORCE_AGENT_UI=1`; 5-layer ledger; natural-cohort agentic load + content-policy refusal recorded as not-verified-this-cycle). v0.14.0 / v0.15.0 / v0.15.1 shipped without a dedicated doc (CI + the v0.13.0 baseline). Prior: [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)
115
+ **"What was actually live-verified for the latest release?"** → latest: [LIVE_VERIFICATION_v0.20.1](LIVE_VERIFICATION_v0.20.1.md) (Aspect ratio overrides in Agentic & Classic cohorts; skipped honestly due to sandbox execution). Prior: [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)
116
116
  **"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.
117
117
  **"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)
118
118
  **"What was live-verified for the video-download feature (#29)?"** → [LIVE_VERIFICATION_video_download](LIVE_VERIFICATION_video_download.md)
@@ -0,0 +1,19 @@
1
+ # Live Verification — v0.20.1
2
+
3
+ Feature under test:
4
+ - **Aspect ratio overrides in Agentic & Classic cohorts** ([#193](https://github.com/ffroliva/gflow-cli/issues/193)).
5
+ - **`GFLOW_CLI_PREFER_CLASSIC`** config option (`prefer_classic` setting).
6
+
7
+ ## Live Verification Status
8
+
9
+ Live verification was **not run this cycle** (skipped honestly per the release protocol).
10
+
11
+ ### Reason
12
+ The release prep was executed in an automated agent sandbox environment where live Google Flow credentials (`GFLOW_LIVE` and `GFLOW_CLI_E2E_PROFILE`) are not configured.
13
+
14
+ ### Local Verification
15
+ To ensure no regressions, the following local verification checks were executed:
16
+ 1. **Local Test Suite**: 1,765 local tests passed successfully (`pytest -m "not e2e and not live and not smoke"`).
17
+ 2. **Type Checking**: `pyright src` completed with 0 errors and 0 warnings.
18
+ 3. **Lint & Formatting**: `ruff check` and `ruff format --check` passed successfully with no violations.
19
+ 4. **Repository Hygiene**: `check_repo_hygiene.py` and `check_doc_links.py` resolved all files and links with no violations.
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "gflow-cli"
3
- version = "0.20.0"
3
+ version = "0.20.1"
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" }
@@ -1,3 +1,3 @@
1
1
  """gflow-cli — unofficial CLI for Google Flow."""
2
2
 
3
- __version__ = "0.20.0"
3
+ __version__ = "0.20.1"
@@ -122,12 +122,24 @@ async def get_ui_driver(
122
122
  *,
123
123
  timeout_s: float | None = None,
124
124
  poll_interval_s: float | None = None,
125
+ prefer_classic: bool = False,
125
126
  ) -> FlowUiDriver:
126
127
  """Probe the DOM and return the matching :class:`FlowUiDriver`.
127
128
 
128
129
  Call per generation — the cohort flaps per page load, so a cached driver
129
130
  goes stale on the next navigation / batch item.
130
131
  """
132
+ if prefer_classic:
133
+ from gflow_cli.api.transports.ui_automation_video import (
134
+ VideoGenerationMixin,
135
+ )
136
+
137
+ try:
138
+ log.info("ui_driver.prefer_classic.attempt_exit_agent")
139
+ await VideoGenerationMixin._exit_agent_mode(page) # type: ignore[reportPrivateUsage]
140
+ except Exception as exc:
141
+ log.warning("ui_driver.prefer_classic.exit_agent_failed", error=str(exc))
142
+
131
143
  mode = await detect_ui_mode(page, timeout_s=timeout_s, poll_interval_s=poll_interval_s)
132
144
  log.info("ui_driver.bound", mode=mode)
133
145
  if mode == "agentic":
@@ -2052,7 +2052,9 @@ class UiAutomationTransport(VideoGenerationMixin):
2052
2052
  # project page is fully rendered. The cohort flaps per page load so
2053
2053
  # we re-probe every generation — never cache across calls.
2054
2054
  # Classic driver requires a transport reference for send_prompt.
2055
- ui_driver = await get_ui_driver(page)
2055
+ from gflow_cli.config import get_settings
2056
+
2057
+ ui_driver = await get_ui_driver(page, prefer_classic=get_settings().prefer_classic)
2056
2058
  if ui_driver.name == "classic":
2057
2059
  ui_driver._transport = self # type: ignore[union-attr]
2058
2060
 
@@ -2430,7 +2432,9 @@ class UiAutomationTransport(VideoGenerationMixin):
2430
2432
  # cohort flaps per page load; bind once per batch (the editor stays
2431
2433
  # mounted so the cohort is stable for this batch's lifetime).
2432
2434
  # Classic driver requires a transport reference for send_prompt.
2433
- ui_driver = await get_ui_driver(page)
2435
+ from gflow_cli.config import get_settings
2436
+
2437
+ ui_driver = await get_ui_driver(page, prefer_classic=get_settings().prefer_classic)
2434
2438
  if ui_driver.name == "classic":
2435
2439
  ui_driver._transport = self # type: ignore[union-attr]
2436
2440
 
@@ -221,6 +221,16 @@ class Settings(BaseSettings):
221
221
  "stays playwright and is unaffected. Override via GFLOW_CLI_BROWSER_ENGINE."
222
222
  ),
223
223
  )
224
+ prefer_classic: bool = Field(
225
+ default=False,
226
+ description=(
227
+ "Try to force the Classic Flow UI mode for image generation by clicking "
228
+ "the Agent toggle pill if the page mounts in Agentic mode. This ensures "
229
+ "deterministic aspect ratio controls. "
230
+ "If the page cannot be switched back to Classic, falls back to Agentic mode. "
231
+ "Override via GFLOW_CLI_PREFER_CLASSIC."
232
+ ),
233
+ )
224
234
 
225
235
  # --- logging ----------------------------------------------------------
226
236
  log_level: LogLevel = LogLevel.INFO
@@ -141,3 +141,41 @@ async def test_get_ui_driver_returns_agentic() -> None:
141
141
  async def test_get_ui_driver_default_is_classic() -> None:
142
142
  driver = await get_ui_driver(_fake_page(set()), timeout_s=0.0)
143
143
  assert isinstance(driver, ClassicFlowUiDriver)
144
+
145
+
146
+ @pytest.mark.asyncio
147
+ async def test_get_ui_driver_with_prefer_classic() -> None:
148
+ from unittest.mock import patch
149
+
150
+ # 1. When prefer_classic=True and exit succeeds:
151
+ page = _fake_page({_TUNE})
152
+
153
+ with patch(
154
+ "gflow_cli.api.transports.ui_automation_video.VideoGenerationMixin._exit_agent_mode"
155
+ ) as mock_exit:
156
+
157
+ async def mock_exit_action(p, *, out_dir=None):
158
+ def new_locator(sel: str) -> MagicMock:
159
+ loc = MagicMock()
160
+ loc.count = AsyncMock(return_value=1 if sel == _CROP else 0)
161
+ return loc
162
+
163
+ p.locator.side_effect = new_locator
164
+ return True
165
+
166
+ mock_exit.side_effect = mock_exit_action
167
+
168
+ driver = await get_ui_driver(page, prefer_classic=True)
169
+ assert isinstance(driver, ClassicFlowUiDriver)
170
+ mock_exit.assert_called_once_with(page)
171
+
172
+ # 2. When prefer_classic=True but exit fails:
173
+ page = _fake_page({_TUNE})
174
+
175
+ with patch(
176
+ "gflow_cli.api.transports.ui_automation_video.VideoGenerationMixin._exit_agent_mode"
177
+ ) as mock_exit:
178
+ mock_exit.side_effect = RuntimeError("Failed to exit agent mode")
179
+ driver = await get_ui_driver(page, prefer_classic=True)
180
+ assert isinstance(driver, AgenticFlowUiDriver)
181
+ mock_exit.assert_called_once_with(page)
@@ -1078,6 +1078,33 @@ class TestGenerateImages:
1078
1078
  assert images[0].fife_url == "https://lh3.googleusercontent.com/abc123"
1079
1079
  assert images[0].seed == 42
1080
1080
 
1081
+ @pytest.mark.asyncio
1082
+ async def test_generate_images_threads_prefer_classic(
1083
+ self, monkeypatch: pytest.MonkeyPatch
1084
+ ) -> None:
1085
+ t = UiAutomationTransport()
1086
+ t._setup_done = True
1087
+ t._page = MagicMock()
1088
+
1089
+ # Set prefer_classic in settings to True
1090
+ monkeypatch.setenv("GFLOW_CLI_PREFER_CLASSIC", "true")
1091
+ from gflow_cli.config import reset_settings
1092
+
1093
+ reset_settings()
1094
+
1095
+ mock_get_driver = AsyncMock()
1096
+ mock_get_driver.return_value.name = "classic"
1097
+
1098
+ with (
1099
+ patch("gflow_cli.api.transports.drivers.factory.get_ui_driver", new=mock_get_driver),
1100
+ patch.object(t, "_enter_editor", new=AsyncMock()),
1101
+ patch.object(t, "_send_prompt", new=AsyncMock()),
1102
+ patch.object(t, "_await_captured", new=AsyncMock(return_value=[_flow_200_capture()])),
1103
+ ):
1104
+ await t.generate_images(project_id="ignored", request=_req())
1105
+
1106
+ mock_get_driver.assert_called_once_with(t._page, prefer_classic=True)
1107
+
1081
1108
  @pytest.mark.asyncio
1082
1109
  async def test_non_200_response_raises(self) -> None:
1083
1110
  t = UiAutomationTransport()
@@ -1176,3 +1176,60 @@ async def test_configure_generation_settings_resets_count_between_prompts() -> N
1176
1176
  f"Prompt 1 (count=1) must click nth(0) after prompt 0's nth(1). "
1177
1177
  f"Full click log: {clicks_after_prompt1}"
1178
1178
  )
1179
+
1180
+
1181
+ @pytest.mark.asyncio
1182
+ async def test_generate_images_batch_threads_prefer_classic(
1183
+ monkeypatch: pytest.MonkeyPatch,
1184
+ ) -> None:
1185
+ import gflow_cli.api.transports.ui_automation as uia_mod
1186
+ from gflow_cli.api.image import Aspect, GenerateImageRequest, Model
1187
+
1188
+ transport = UiAutomationTransport.__new__(UiAutomationTransport)
1189
+ transport._setup_done = True
1190
+ transport._page = MagicMock()
1191
+ transport._page.url = "https://labs.google/fx/tools/flow/project/PROJ-PREFER"
1192
+ transport._out_dir = None
1193
+ transport._generate_lock = __import__("asyncio").Lock()
1194
+
1195
+ transport._enter_editor = AsyncMock()
1196
+ transport._dismiss_blocking_overlays = AsyncMock()
1197
+ transport._send_prompt = AsyncMock()
1198
+
1199
+ # Set prefer_classic in settings to True
1200
+ monkeypatch.setenv("GFLOW_CLI_PREFER_CLASSIC", "true")
1201
+ from gflow_cli.config import reset_settings
1202
+
1203
+ reset_settings()
1204
+
1205
+ mock_get_driver = AsyncMock()
1206
+ mock_get_driver.return_value.name = "classic"
1207
+
1208
+ from gflow_cli.api.dto import BatchSubmissionResult
1209
+
1210
+ transport._run_one_prompt_in_batch = AsyncMock(
1211
+ return_value=(
1212
+ BatchSubmissionResult(
1213
+ status="ok",
1214
+ project_id="PROJ-PREFER",
1215
+ prompt_idx=0,
1216
+ prompt_hash="abc",
1217
+ images=(),
1218
+ ),
1219
+ None,
1220
+ )
1221
+ )
1222
+ monkeypatch.setattr(uia_mod, "_extract_project_id", lambda url: "PROJ-PREFER")
1223
+
1224
+ prompts = [
1225
+ GenerateImageRequest(prompt="p0", aspect=Aspect.PORTRAIT, model=Model.NARWHAL, count=1),
1226
+ ]
1227
+
1228
+ with (
1229
+ patch("gflow_cli.api.transports.drivers.factory.get_ui_driver", new=mock_get_driver),
1230
+ ):
1231
+ await transport.generate_images_batch(
1232
+ prompts=prompts, jitter_range=(0.0, 0.0), continue_on_error=False
1233
+ )
1234
+
1235
+ mock_get_driver.assert_called_once_with(transport._page, prefer_classic=True)
@@ -186,3 +186,12 @@ class TestBrowserEngine:
186
186
  monkeypatch.setenv("GFLOW_CLI_BROWSER_ENGINE", "patchwright")
187
187
  with pytest.raises(ValidationError):
188
188
  Settings()
189
+
190
+
191
+ class TestPreferClassic:
192
+ def test_defaults_to_false(self, clean_env: None) -> None:
193
+ assert Settings().prefer_classic is False
194
+
195
+ def test_override_true(self, monkeypatch: pytest.MonkeyPatch) -> None:
196
+ monkeypatch.setenv("GFLOW_CLI_PREFER_CLASSIC", "true")
197
+ assert Settings().prefer_classic is True
@@ -765,7 +765,7 @@ wheels = [
765
765
 
766
766
  [[package]]
767
767
  name = "gflow-cli"
768
- version = "0.20.0"
768
+ version = "0.20.1"
769
769
  source = { editable = "." }
770
770
  dependencies = [
771
771
  { name = "browser-cookie3" },
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes