gflow-cli 0.8.1__tar.gz → 0.9.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 (293) hide show
  1. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/.env.template +9 -0
  2. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/AGENTS.md +2 -2
  3. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/CHANGELOG.md +122 -1
  4. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/KNOWN_ISSUES.md +60 -1
  5. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/PKG-INFO +21 -5
  6. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/PLAN.md +31 -12
  7. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/README.md +20 -4
  8. gflow_cli-0.9.0/ROADMAP.md +45 -0
  9. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/ARCHITECTURE.md +5 -1
  10. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/CONFIGURATION.md +34 -0
  11. gflow_cli-0.9.0/docs/DATA_LAYER.md +399 -0
  12. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/INDEX.md +9 -1
  13. gflow_cli-0.9.0/docs/LIVE_VERIFICATION_data_layer.md +209 -0
  14. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/LIVE_VERIFICATION_v0.8.1.md +28 -21
  15. gflow_cli-0.9.0/docs/LIVE_VERIFICATION_v0.9.0.md +107 -0
  16. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/LIVE_VERIFICATION_video_download.md +5 -3
  17. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/PROJECT_STATUS.md +13 -2
  18. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/SECURITY.md +33 -0
  19. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/USAGE.md +148 -36
  20. gflow_cli-0.9.0/docs/superpowers/notes/v0.9.0-schema-reconciliation.md +108 -0
  21. gflow_cli-0.9.0/docs/superpowers/plans/2026-05-23-locale-agnostic-selectors.md +108 -0
  22. gflow_cli-0.9.0/docs/superpowers/plans/2026-05-24-data-layer.md +2452 -0
  23. gflow_cli-0.9.0/docs/superpowers/plans/2026-05-24-v0.9.0-release-implementation.md +2123 -0
  24. gflow_cli-0.9.0/docs/superpowers/specs/2026-05-23-locale-agnostic-selectors.md +66 -0
  25. gflow_cli-0.9.0/docs/superpowers/specs/2026-05-23-readme-v0.8.1-refresh-design.md +359 -0
  26. gflow_cli-0.9.0/docs/superpowers/specs/2026-05-24-data-layer-design.md +403 -0
  27. gflow_cli-0.9.0/docs/superpowers/specs/2026-05-24-v0.9.0-release-design.md +204 -0
  28. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/llms.txt +3 -1
  29. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/pyproject.toml +1 -1
  30. gflow_cli-0.9.0/scripts/dev/capture_image_add_media_dom.py +184 -0
  31. gflow_cli-0.9.0/scripts/dev/capture_locale_invariants.py +87 -0
  32. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/src/gflow_cli/__init__.py +1 -1
  33. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/src/gflow_cli/api/client.py +99 -30
  34. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/src/gflow_cli/api/dto.py +2 -0
  35. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/src/gflow_cli/api/image.py +5 -0
  36. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/src/gflow_cli/api/transports/_common.py +16 -0
  37. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/src/gflow_cli/api/transports/base.py +25 -1
  38. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/src/gflow_cli/api/transports/ui_automation.py +82 -15
  39. gflow_cli-0.9.0/src/gflow_cli/api/transports/ui_automation_video.py +1013 -0
  40. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/src/gflow_cli/api/video.py +124 -5
  41. gflow_cli-0.9.0/src/gflow_cli/auth/internal_chromium.py +158 -0
  42. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/src/gflow_cli/auth/real_chrome.py +80 -67
  43. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/src/gflow_cli/browser_manager.py +10 -19
  44. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/src/gflow_cli/cli.py +2 -0
  45. gflow_cli-0.9.0/src/gflow_cli/cli_data.py +299 -0
  46. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/src/gflow_cli/cli_image.py +257 -159
  47. gflow_cli-0.9.0/src/gflow_cli/cli_video.py +464 -0
  48. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/src/gflow_cli/config.py +19 -0
  49. gflow_cli-0.9.0/src/gflow_cli/data/__init__.py +5 -0
  50. gflow_cli-0.9.0/src/gflow_cli/data/migrations/0001_initial.sql +100 -0
  51. gflow_cli-0.9.0/src/gflow_cli/data/migrations/__init__.py +1 -0
  52. gflow_cli-0.9.0/src/gflow_cli/data/models.py +179 -0
  53. gflow_cli-0.9.0/src/gflow_cli/data/queries.py +326 -0
  54. gflow_cli-0.9.0/src/gflow_cli/data/recorder.py +407 -0
  55. gflow_cli-0.9.0/src/gflow_cli/data/redaction.py +48 -0
  56. gflow_cli-0.9.0/src/gflow_cli/data/repository.py +585 -0
  57. gflow_cli-0.9.0/src/gflow_cli/data/store.py +239 -0
  58. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/src/gflow_cli/errors.py +32 -0
  59. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/src/gflow_cli/exceptions.py +3 -0
  60. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/src/gflow_cli/image_batch.py +105 -20
  61. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/src/gflow_cli/paths.py +5 -0
  62. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/api/test_client.py +60 -0
  63. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/api/test_concurrency.py +27 -0
  64. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/api/test_video.py +80 -0
  65. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/api/transports/test_common.py +16 -0
  66. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/api/transports/test_ui_automation.py +43 -0
  67. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/api/transports/test_ui_automation_video.py +118 -6
  68. gflow_cli-0.9.0/tests/cli/test_cli_data.py +81 -0
  69. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/cli/test_cli_image.py +208 -18
  70. gflow_cli-0.9.0/tests/cli/test_cli_video.py +208 -0
  71. gflow_cli-0.9.0/tests/data/test_packaging.py +30 -0
  72. gflow_cli-0.9.0/tests/data/test_recorder.py +155 -0
  73. gflow_cli-0.9.0/tests/data/test_redaction.py +31 -0
  74. gflow_cli-0.9.0/tests/data/test_repository.py +272 -0
  75. gflow_cli-0.9.0/tests/data/test_settings_and_errors.py +47 -0
  76. gflow_cli-0.9.0/tests/data/test_store_migrations.py +114 -0
  77. gflow_cli-0.9.0/tests/e2e/test_data_layer_e2e.py +439 -0
  78. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/e2e/test_transports_e2e.py +66 -0
  79. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/features/test_image_steps.py +1 -0
  80. gflow_cli-0.9.0/tests/fixtures/seeded_catalog.py +226 -0
  81. gflow_cli-0.9.0/tests/image_batch/__init__.py +0 -0
  82. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/image_batch/test_image_manifest.py +222 -1
  83. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/image_batch/test_observability_events.py +78 -0
  84. gflow_cli-0.9.0/tests/smoke/__init__.py +0 -0
  85. gflow_cli-0.9.0/tests/test_cli_data.py +147 -0
  86. gflow_cli-0.9.0/tests/test_data_queries.py +151 -0
  87. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/test_errors.py +2 -2
  88. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/uv.lock +1 -1
  89. gflow_cli-0.8.1/src/gflow_cli/api/transports/ui_automation_video.py +0 -543
  90. gflow_cli-0.8.1/src/gflow_cli/auth/internal_chromium.py +0 -147
  91. gflow_cli-0.8.1/src/gflow_cli/cli_video.py +0 -153
  92. gflow_cli-0.8.1/tests/cli/test_cli_video.py +0 -68
  93. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/.claude/README.md +0 -0
  94. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/.claude/commands/gflow/changelog.md +0 -0
  95. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/.claude/commands/gflow/check.md +0 -0
  96. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/.claude/commands/gflow/doc-review.md +0 -0
  97. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/.claude/commands/gflow/known-issues.md +0 -0
  98. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/.claude/commands/gflow/plan.md +0 -0
  99. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/.claude/commands/gflow/release.md +0 -0
  100. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/.continue-here.md +0 -0
  101. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/.gitattributes +0 -0
  102. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/.github/CODEOWNERS +0 -0
  103. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  104. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/.github/copilot-instructions.md +0 -0
  105. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/.github/dependabot.yml +0 -0
  106. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/.github/workflows/ci.yml +0 -0
  107. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/.github/workflows/external-pr-triage.yml +0 -0
  108. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/.github/workflows/release.yml +0 -0
  109. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/.gitignore +0 -0
  110. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/.gitleaks.toml +0 -0
  111. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/.planning/todos/pending/2026-05-11-add-project-logo-and-docs-site-promotion-plan.md +0 -0
  112. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/.planning/todos/pending/pr-38-review.md +0 -0
  113. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/.pre-commit-config.yaml +0 -0
  114. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/.secrets.baseline +0 -0
  115. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/CLAUDE.md +0 -0
  116. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/CONFIGURATION.md +0 -0
  117. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/CONTRIBUTING.md +0 -0
  118. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/DISCLAIMER.md +0 -0
  119. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/LICENSE +0 -0
  120. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/RELEASE.md +0 -0
  121. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/AGENT_GUIDE.md +0 -0
  122. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/AUTHENTICATION.md +0 -0
  123. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/DEBUGGING.md +0 -0
  124. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/DEVELOPMENT.md +0 -0
  125. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/GITHUB.md +0 -0
  126. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/LIVE_VERIFICATION_image_batch.md +0 -0
  127. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/LIVE_VERIFICATION_v0.7.0.md +0 -0
  128. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/USER_GUIDE.md +0 -0
  129. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/assets/example-run.gif +0 -0
  130. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/2026-05-17-issue-15-handover.md +0 -0
  131. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/plans/2026-05-09-image-mvp-orchestration.md +0 -0
  132. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/plans/2026-05-09-image-mvp.md +0 -0
  133. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/plans/2026-05-09-video-mvp-orchestration.md +0 -0
  134. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/plans/2026-05-09-video-mvp.md +0 -0
  135. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/plans/2026-05-10-phase-4-hardening-orchestration.md +0 -0
  136. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/plans/2026-05-10-phase-4-hardening.md +0 -0
  137. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/plans/2026-05-14-shell-multi-prompt/2026-05-14-shell-multi-prompt-orchestration.md +0 -0
  138. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/plans/2026-05-14-shell-multi-prompt/COUNCIL_FINAL_ARCH.md +0 -0
  139. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/plans/2026-05-14-shell-multi-prompt/COUNCIL_FINAL_SEC_UX.md +0 -0
  140. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/plans/2026-05-14-shell-multi-prompt/COUNCIL_REVIEW_CODE.md +0 -0
  141. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/plans/2026-05-14-shell-multi-prompt/COUNCIL_REVIEW_GEMINI.md +0 -0
  142. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/plans/2026-05-14-shell-multi-prompt/COUNCIL_REVIEW_SECURITY.md +0 -0
  143. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/plans/2026-05-14-shell-multi-prompt/IMPLEMENTATION_REVIEW_PYTHON.md +0 -0
  144. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/plans/2026-05-14-shell-multi-prompt/IMPLEMENTATION_REVIEW_SECURITY.md +0 -0
  145. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/plans/2026-05-14-shell-multi-prompt/PLAN.md +0 -0
  146. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/plans/2026-05-14-shell-multi-prompt/PLAN_REVIEW_CODE.md +0 -0
  147. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/plans/2026-05-14-shell-multi-prompt/PLAN_REVIEW_FOLLOWUP.md +0 -0
  148. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/plans/2026-05-14-shell-multi-prompt/PLAN_REVIEW_PLANNER.md +0 -0
  149. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/plans/2026-05-14-shell-multi-prompt/PLAN_REVIEW_SECURITY.md +0 -0
  150. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/plans/2026-05-14-shell-multi-prompt/PLAN_REVIEW_SECURITY_FOLLOWUP.md +0 -0
  151. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/plans/2026-05-15-auth-login-real-chrome/COUNCIL_FINAL_SEC_UX_VERIFIED.md +0 -0
  152. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/plans/2026-05-15-auth-login-real-chrome/COUNCIL_REVIEW_PLAN_SECURITY.md +0 -0
  153. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/plans/2026-05-15-auth-login-real-chrome/COUNCIL_REVIEW_SPEC_SECURITY.md +0 -0
  154. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/plans/2026-05-15-auth-login-real-chrome/PLAN.md +0 -0
  155. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/plans/2026-05-15-auth-login-real-chrome/orchestration.md +0 -0
  156. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/plans/2026-05-17-e2e-test-coverage.md +0 -0
  157. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/plans/2026-05-17-issue-15-auth-verification-fix.md +0 -0
  158. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/plans/2026-05-17-issue-15-i2v-bearer-auth.md +0 -0
  159. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/plans/2026-05-17-issue-15-orchestration.md +0 -0
  160. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/plans/2026-05-18-video-phase0-submit-spike.md +0 -0
  161. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/plans/2026-05-19-video-phase-a-execution-state.md +0 -0
  162. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/plans/2026-05-19-video-phase-a-orchestration.md +0 -0
  163. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/plans/2026-05-19-video-phase-a-t2v.md +0 -0
  164. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/plans/2026-05-20-video-download-t2v-cli.md +0 -0
  165. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/plans/2026-05-21-multi-image-prompt-orchestration.md +0 -0
  166. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/plans/2026-05-21-multi-image-prompt.md +0 -0
  167. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/plans/2026-05-22-pr-38-review.md +0 -0
  168. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/plans/2026-05-22-stay-mounted-batch-session-plan.md +0 -0
  169. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/specs/2026-05-10-phase-4-hardening-design.md +0 -0
  170. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/specs/2026-05-14-shell-multi-prompt-design.md +0 -0
  171. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/specs/2026-05-15-auth-login-real-chrome-design.md +0 -0
  172. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/specs/2026-05-17-e2e-test-coverage-design.md +0 -0
  173. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/specs/2026-05-17-i2v-uploadimage-401-bearer-auth-design.md +0 -0
  174. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/specs/2026-05-17-issue-15-auth-verification-fix-design.md +0 -0
  175. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/specs/2026-05-17-issue-15-root-cause-findings.md +0 -0
  176. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/specs/2026-05-18-ui-automation-video-generation-design.md +0 -0
  177. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/specs/2026-05-21-multi-image-prompt-design.md +0 -0
  178. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/specs/2026-05-22-pr-38-review-design.md +0 -0
  179. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/specs/2026-05-22-stay-mounted-batch-session-design.md +0 -0
  180. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/verifications/2026-05-11-phase-4-stage-g.md +0 -0
  181. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/examples/README.md +0 -0
  182. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/examples/batch_from_config.py +0 -0
  183. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/examples/multi_prompt_t2i.py +0 -0
  184. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/examples/sample_config.json +0 -0
  185. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/examples/sample_prompts.txt +0 -0
  186. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/examples/single_image_t2i.py +0 -0
  187. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/samples/README.md +0 -0
  188. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/samples/captured/01_upload_image.json +0 -0
  189. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/samples/captured/02_batchAsyncGenerateVideoText.json +0 -0
  190. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/samples/captured/03_batchCheckAsyncVideoGenerationStatus.json +0 -0
  191. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/samples/captured/04_archive_workflow.json +0 -0
  192. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/samples/captured/05_createProject.json +0 -0
  193. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/samples/captured/06_batchGenerateImages.json +0 -0
  194. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/samples/captured/07_batchGenerateImages_seeded.json +0 -0
  195. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/samples/captured/08_batchAsyncGenerateVideoStartAndEndImage.json +0 -0
  196. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/samples/captured/09_batchAsyncGenerateVideoReferenceImages.json +0 -0
  197. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/samples/captured/10_batchCheckAsyncVideoGenerationStatus_successful.json +0 -0
  198. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/samples/captured/11_batchCheckAsyncVideoGenerationStatus_failed.json +0 -0
  199. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/scripts/ci/check_doc_links.py +0 -0
  200. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/scripts/ci/check_repo_hygiene.py +0 -0
  201. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/scripts/debug_editor.py +0 -0
  202. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/scripts/debug_gen_settings.py +0 -0
  203. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/scripts/debug_settings.py +0 -0
  204. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/scripts/dev/active_plan.py +0 -0
  205. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/scripts/dev/monitor_pr_38.py +0 -0
  206. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/scripts/diag_capture_flow_traffic.py +0 -0
  207. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/scripts/diag_recaptcha_mint.py +0 -0
  208. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/scripts/record_demo.ps1 +0 -0
  209. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/scripts/smoke_image.py +0 -0
  210. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/scripts/smoke_real_chrome_image.py +0 -0
  211. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/scripts/smoke_video_editor.py +0 -0
  212. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/scripts/smoke_worker_style.py +0 -0
  213. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/scripts/verify_chrome_auth_viability.py +0 -0
  214. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/skills/README.md +0 -0
  215. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/skills/gflow-cli/SKILL.md +0 -0
  216. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/sonar-project.properties +0 -0
  217. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/src/gflow_cli/__main__.py +0 -0
  218. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/src/gflow_cli/_cli_helpers.py +0 -0
  219. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/src/gflow_cli/api/__init__.py +0 -0
  220. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/src/gflow_cli/api/_retry.py +0 -0
  221. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/src/gflow_cli/api/recaptcha.py +0 -0
  222. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/src/gflow_cli/api/routes.py +0 -0
  223. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/src/gflow_cli/api/transports/__init__.py +0 -0
  224. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/src/gflow_cli/api/transports/_fingerprint.py +0 -0
  225. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/src/gflow_cli/api/transports/experimental/__init__.py +0 -0
  226. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/src/gflow_cli/api/transports/experimental/bearer.py +0 -0
  227. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/src/gflow_cli/api/transports/experimental/evaluate_fetch.py +0 -0
  228. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/src/gflow_cli/api/transports/experimental/sapisidhash.py +0 -0
  229. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/src/gflow_cli/auth/__init__.py +0 -0
  230. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/src/gflow_cli/auth/base.py +0 -0
  231. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/src/gflow_cli/auth/factory.py +0 -0
  232. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/src/gflow_cli/auth/strategies.py +0 -0
  233. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/src/gflow_cli/auth/verification.py +0 -0
  234. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/src/gflow_cli/cli_run.py +0 -0
  235. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/src/gflow_cli/manifest.py +0 -0
  236. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/src/gflow_cli/observability.py +0 -0
  237. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/src/gflow_cli/profile_store.py +0 -0
  238. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tasks/lessons.md +0 -0
  239. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/test_assets/sample_batch.json +0 -0
  240. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/test_assets/sample_batch.tsv +0 -0
  241. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/test_assets/sample_batch_invalid.tsv +0 -0
  242. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/__init__.py +0 -0
  243. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/api/__init__.py +0 -0
  244. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/api/test_client_image.py +0 -0
  245. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/api/test_dto.py +0 -0
  246. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/api/test_image.py +0 -0
  247. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/api/test_image_dto.py +0 -0
  248. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/api/test_recaptcha.py +0 -0
  249. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/api/test_retry.py +0 -0
  250. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/api/test_routes.py +0 -0
  251. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/api/transports/__init__.py +0 -0
  252. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/api/transports/test_base.py +0 -0
  253. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/api/transports/test_bearer.py +0 -0
  254. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/api/transports/test_evaluate_fetch.py +0 -0
  255. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/api/transports/test_factory.py +0 -0
  256. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/api/transports/test_fingerprint.py +0 -0
  257. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/api/transports/test_sapisidhash.py +0 -0
  258. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/api/transports/test_ui_automation_batch.py +0 -0
  259. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/api/transports/test_ui_automation_image_mode.py +0 -0
  260. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/auth/strategies/test_factory.py +0 -0
  261. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/auth/strategies/test_strategies.py +0 -0
  262. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/auth/test_verification.py +0 -0
  263. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/cli/__init__.py +0 -0
  264. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/cli/test_cli_image_seed_removed.py +0 -0
  265. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/cli/test_cli_run.py +0 -0
  266. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/cli/test_error_handling.py +0 -0
  267. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/cli/test_helpers.py +0 -0
  268. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/cli/test_t2i_multi_prompt.py +0 -0
  269. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/conftest.py +0 -0
  270. {gflow_cli-0.8.1/tests/e2e → gflow_cli-0.9.0/tests/data}/__init__.py +0 -0
  271. {gflow_cli-0.8.1/tests/features → gflow_cli-0.9.0/tests/e2e}/__init__.py +0 -0
  272. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/e2e/conftest.py +0 -0
  273. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/e2e/test_auth_verification_e2e.py +0 -0
  274. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/e2e/test_image_batch_e2e.py +0 -0
  275. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/e2e/test_video_t2v_e2e.py +0 -0
  276. {gflow_cli-0.8.1/tests/image_batch → gflow_cli-0.9.0/tests/features}/__init__.py +0 -0
  277. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/features/auth.feature +0 -0
  278. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/features/auth_login.feature +0 -0
  279. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/features/conftest.py +0 -0
  280. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/features/image.feature +0 -0
  281. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/features/test_auth_login_steps.py +0 -0
  282. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/features/test_auth_steps.py +0 -0
  283. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/features/test_step_collision_guard.py +0 -0
  284. {gflow_cli-0.8.1/tests/smoke → gflow_cli-0.9.0/tests/fixtures}/__init__.py +0 -0
  285. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/smoke/test_real_flow.py +0 -0
  286. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/test_auth.py +0 -0
  287. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/test_browser_manager.py +0 -0
  288. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/test_config.py +0 -0
  289. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/test_manifest.py +0 -0
  290. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/test_observability.py +0 -0
  291. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/test_paths.py +0 -0
  292. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/test_profile_store.py +0 -0
  293. {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/test_smoke.py +0 -0
@@ -77,3 +77,12 @@
77
77
  # (Google's bot-detection sometimes refuses headless Chromium but accepts a
78
78
  # visible window). The session is still reused from the persistent profile.
79
79
  # GFLOW_CLI_HEADLESS=true
80
+
81
+ # BCP-47 locale tag passed to Playwright's launch `locale=` parameter
82
+ # (controls Accept-Language only — Chrome's UI language is forced to
83
+ # en-US via the `--lang=en-US` launch arg regardless of this setting, so
84
+ # Flow stays on /fx/tools/flow/ instead of /fx/<locale>/). Default:
85
+ # `en-US`. Override to capture locale-invariant DOM via
86
+ # scripts/dev/capture_locale_invariants.py or to live-verify a non-EN
87
+ # language end-to-end (see KNOWN_ISSUES § issue #24).
88
+ # GFLOW_CLI_LOCALE=en-US
@@ -8,7 +8,7 @@ Supported tools that auto-discover this file: Cursor, Codex, Aider, Gemini CLI,
8
8
 
9
9
  - Unofficial Python CLI for [Google Flow](https://labs.google/fx/tools/flow) — drives Veo (image-to-video, text-to-video) and Imagen (text-to-image) generations from the terminal by reverse-engineering Flow's private REST API at `aisandbox-pa.googleapis.com`.
10
10
  - Python 3.11+ · `uv`-managed · `hatchling` builds · Playwright Chromium transport · `pyright` strict · `ruff` · `pytest`.
11
- - Single-package modular monolith. Top-level modules under `src/gflow_cli/`: `api/`, `auth/`, `browser_manager.py`, `cli.py`, `_cli_helpers.py`, `cli_image.py`, `cli_run.py`, `cli_video.py`, `config.py`, `errors.py`, `exceptions.py`, `image_batch.py`, `manifest.py`, `observability.py`, `paths.py`, `profile_store.py`.
11
+ - Single-package modular monolith. Top-level modules under `src/gflow_cli/`: `api/`, `auth/`, `browser_manager.py`, `cli.py`, `_cli_helpers.py`, `cli_data.py`, `cli_image.py`, `cli_run.py`, `cli_video.py`, `config.py`, `data/`, `errors.py`, `exceptions.py`, `image_batch.py`, `manifest.py`, `observability.py`, `paths.py`, `profile_store.py`.
12
12
  - Requires a Google AI Ultra or Pro subscription with Flow access. All generations bill against the user's own Google account.
13
13
 
14
14
  ## Headed-browser dependency (architectural reality)
@@ -53,7 +53,7 @@ Or invoke the wrapper: `/gflow:check`.
53
53
 
54
54
  - Type hints everywhere; `pyright` strict on `src/gflow_cli`.
55
55
  - Structured logging only (`structlog`) — **never** raw `print()` or `import logging` in `src/`.
56
- - Errors as RFC 9457 Problem Details with stable per-class exit codes (3–15). See `src/gflow_cli/errors.py::EXIT_CODE_MAP` for the complete mapping.
56
+ - Errors as RFC 9457 Problem Details with stable per-class exit codes (3–16, where 16 is the `DataStoreError` family from `gflow_cli.data`). See `src/gflow_cli/errors.py::EXIT_CODE_MAP` for the complete mapping.
57
57
  - 100-char line length, `ruff` configured. Imports sorted by `ruff` (isort rules).
58
58
 
59
59
  ## PR instructions
@@ -7,6 +7,125 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.9.0] — 2026-05-25
11
+
12
+ > **Maturity & Visibility release.** Surfaces the SQLite catalog (PR #52/#58)
13
+ > via a read-only `gflow data list {projects,images,videos,profiles}` CLI,
14
+ > publishes `ROADMAP.md`, and ships the locale-agnostic media-dialog
15
+ > selectors that unblock non-English Chrome profiles. Plus the previously-
16
+ > unreleased video model picker, i2v/r2v, and the I2I ref-attach + model-
17
+ > select fixes. Sponsorship wiring will land in a follow-up patch release
18
+ > once GitHub Sponsors / Buy Me a Coffee accounts are fully provisioned.
19
+
20
+ ### Added
21
+
22
+ - `gflow data list {projects,images,videos,profiles}` — read-only catalog
23
+ query CLI over the local SQLite data layer. Flags: `--limit` (1..1000,
24
+ default 20), `--offset` (≥0, default 0), `--profile NAME`, `--json`.
25
+ Rich table on TTY, JSONL on pipe or `--json`. Default sort: newest first.
26
+ `DataStoreError` family maps to exit code 16. See
27
+ [`docs/DATA_LAYER.md § Querying the data layer`](docs/DATA_LAYER.md#querying-the-data-layer).
28
+ - `ROADMAP.md` at repo root — themed milestones from v0.9 through v1.0 (no
29
+ dates).
30
+ - `gflow video t2v` model picker: `--model` (`omni-flash` | `veo-lite` |
31
+ `veo-fast` | `veo-quality` | `veo-lite-lp`), `--duration` (`4`/`6`/`8`, plus
32
+ `10` for `omni-flash` only), and `--count` (1–4). Driven via the editor's
33
+ generation-settings panel; live-verified against a Pro/Ultra profile.
34
+ - `gflow video i2v <image> "<prompt>"` — image-to-video with a start frame and
35
+ an optional `--end-image` (interpolation). Fires
36
+ `batchAsyncGenerateVideoStartImage` / `…StartAndEndImage`.
37
+ - `gflow video r2v "<prompt>" --ref <img> [--ref …]` — reference-to-video
38
+ (Flow "ingredients"). Model-aware reference cap (omni_flash ≤7, veo_3_1_* ≤3)
39
+ enforced in the request DTO; the transport stops gracefully if Flow hides the
40
+ add-media button at the cap. Fires `batchAsyncGenerateVideoReferenceImages`.
41
+ - `GFLOW_CLI_LOCALE` env var — overrides Playwright's launch `locale=` parameter
42
+ (default: `en-US`). Controls `Accept-Language` only; Chrome's UI language is
43
+ still forced to en-US via `--lang=en-US`. Prep for issue #24 (locale-agnostic
44
+ selectors); live-verified end-to-end with `GFLOW_CLI_LOCALE=pt-BR` against a
45
+ Pro/Ultra account. See `docs/CONFIGURATION.md § GFLOW_CLI_LOCALE`.
46
+ - **Local data layer** — `gflow-cli` now keeps a SQLite catalog of every new
47
+ image, batch, and video operation under `$GFLOW_CLI_DB_PATH` (default:
48
+ `~/.local/share/gflow-cli/data.db`). Records profile, project, asset
49
+ (model / aspect / dimensions / Flow media ID), operation provenance
50
+ (mode / prompt / model / timing / error), input↔output links, and
51
+ downloaded local files. New `gflow data media <id>` command resolves a
52
+ Flow media ID to its origin. `DataRepository` exposes seed-image resolvers
53
+ (`resolve_seed_image_by_path` / `resolve_seed_image` /
54
+ `resolve_latest_image`) — foundation for the upcoming I2V seed-reuse
55
+ path. Pre-Flow store failures exit `16` (`DataStoreError` /
56
+ `DataMigrationError` / `DataIntegrityError`); post-success store
57
+ failures warn and exit `0` (Flow already charged the credits). See
58
+ [`docs/DATA_LAYER.md`](docs/DATA_LAYER.md). (PR #58, stacked on #52.)
59
+
60
+ ### Changed
61
+
62
+ - `MAX_REFERENCE_IMAGES` (in `api/video.py`) now tracks the `omni_flash`
63
+ ceiling of **7** (was **3**). The tighter per-model cap (`veo_3_1_* ≤ 3`) is
64
+ still enforced in `GenerateVideoRequest.__post_init__` when the model is
65
+ known; the constant is only the absolute upper bound. Anyone pinning to the
66
+ old value of 3 should re-check against the per-model caps.
67
+
68
+ ### Fixed
69
+
70
+ - `FlowApiClient.__aenter__` now tears down a partially-launched browser if any
71
+ step after the Playwright driver starts raises (e.g. the persistent-context
72
+ launch, the bootstrap navigation, or `transport.setup`). Python does not call
73
+ `__aexit__` when `__aenter__` raises, so an unguarded failure orphaned the
74
+ chrome process, which then held the profile's user-data-dir lock — the next
75
+ run could not acquire it and spiralled into rapid `about:blank` tabs +
76
+ `TargetClosedError`. Context close + driver stop are now shared by
77
+ `__aenter__`'s guard and `__aexit__` via `_close_browser_resources`.
78
+ - `gflow image i2i --ref <local-file>` now binds the reference through the
79
+ editor's media dialog instead of the REST `uploadImage` endpoint (which 401s —
80
+ same root as #15/#39). Local-path refs ride a new `GenerateImageRequest.ref_paths`
81
+ field and are attached via the inherited R2V `_attach_references` (the image-mode
82
+ add-media dialog is the same `add_2` surface). Bare-UUID `--ref` still flows
83
+ through `refs` unchanged. Re-introduces #50 (reverted in #57 for the account/
84
+ locale variant tracked in #56); the media-dialog selectors are now
85
+ locale-agnostic (see the next entry).
86
+ - The media-dialog upload selectors are now **locale-agnostic** (issue #56/#24).
87
+ `UPLOAD_MEDIA_BUTTON` matched localized text (`has-text('Upload media')`), so on
88
+ a non-English Chrome profile (Flow follows the *Chrome profile* language, which
89
+ the `--lang=en-US` arg cannot override) the click missed and the file chooser
90
+ never opened — a silent ~34s hang. It now anchors on the locale-free `upload`
91
+ icon ligature (`:text-is('upload')`, exact, so it doesn't grab the `Uploads`
92
+ tab), with the original English-text selector kept as a graceful **fallback
93
+ tier** (matches if Google ever changes the icon but keeps the English label);
94
+ 'Add to Prompt' (which has no icon) is selected structurally as the only
95
+ iconless button in the open dialog. If neither tier opens a chooser,
96
+ `_upload_via_open_dialog` raises a clear error + writes a screenshot (no silent
97
+ hang) and points the operator at the Chrome-profile-language workaround. Fixes
98
+ I2I/I2V/R2V upload alike.
99
+ - `gflow image t2i/i2i --model` now actually selects the requested model. It was
100
+ a no-op under `ui_automation` (the wire field was set but the model picker was
101
+ never clicked, so Flow used its UI default). Adds `_select_image_model`.
102
+ - Video selector mismatches: the output-count selector `[id*=-trigger-1]`
103
+ collided with the `-trigger-10` duration tab; the aspect selector matched a
104
+ non-existent `aria-controls*=9_16`; the video-mode tab match was ambiguous.
105
+ All now use exact `[id$=-trigger-X]` suffixes + aria-label text.
106
+
107
+ ### Build
108
+
109
+ - **Wheel build no longer emits duplicate ZIP entries.** An earlier attempt at
110
+ tagging v0.9.0 was rejected by PyPI with HTTP 400 ("Duplicate filename in
111
+ local headers") because `pyproject.toml` had
112
+ `[tool.hatch.build.targets.wheel.force-include]` and
113
+ `[tool.hatch.build.targets.sdist.force-include]` blocks pointing at
114
+ `src/gflow_cli/data/migrations`, on top of the already-comprehensive
115
+ `packages = ["src/gflow_cli"]` directive — hatchling included the
116
+ migrations directory twice (both `__init__.py` and `0001_initial.sql`). The
117
+ force-include blocks have been removed; hatchling's default package
118
+ inclusion already covers `.sql` files inside the package tree. (PR #74.)
119
+
120
+ ### Notes
121
+
122
+ - I2V/R2V image inputs bind through the editor's media dialog (frame slot /
123
+ add-media → "Upload media" → file chooser → "Add to Prompt"). `set_input_files`
124
+ on the generic hidden input only adds to the library and Flow then ignores the
125
+ image (plain Text route). The editor is forced to English via the
126
+ `--lang=en-US` Chromium launch arg because the slot/dialog labels are localized
127
+ with no locale-free anchor.
128
+
10
129
  ## [0.8.1] — 2026-05-23
11
130
 
12
131
  ### Documentation
@@ -826,7 +945,9 @@ shell-script template that branches on these codes.
826
945
 
827
946
  First skeleton. Not functional end-to-end yet.
828
947
 
829
- [Unreleased]: https://github.com/ffroliva/gflow-cli/compare/v0.8.0...HEAD
948
+ [Unreleased]: https://github.com/ffroliva/gflow-cli/compare/v0.9.0...HEAD
949
+ [0.9.0]: https://github.com/ffroliva/gflow-cli/compare/v0.8.1...v0.9.0
950
+ [0.8.1]: https://github.com/ffroliva/gflow-cli/compare/v0.8.0...v0.8.1
830
951
  [0.8.0]: https://github.com/ffroliva/gflow-cli/compare/v0.7.0...v0.8.0
831
952
  [0.7.0]: https://github.com/ffroliva/gflow-cli/compare/v0.6.0a6...v0.7.0
832
953
  [0.6.0a6]: https://github.com/ffroliva/gflow-cli/compare/v0.6.0a5...v0.6.0a6
@@ -319,7 +319,21 @@ issue and not blocked by any code change in this repo.
319
319
 
320
320
  - **Status:** Mitigated · **Severity:** Medium · **Tracking:** [issue #24](https://github.com/ffroliva/gflow-cli/issues/24)
321
321
 
322
- The Phase 7 multi-image-prompt work addressed the count-tab selectors:
322
+ **Progress (2026-05-24, develop / post-v0.8.1, unreleased):**
323
+
324
+ - **PR #51** — Playwright's launch `locale=` is now env-overridable via
325
+ `GFLOW_CLI_LOCALE` (default: `en-US`). Live-verified end-to-end with
326
+ `GFLOW_CLI_LOCALE=pt-BR uv run pytest -m e2e tests/e2e/test_video_t2v_e2e.py`
327
+ (1 credit, ~2.5 MB mp4, `MEDIA_GENERATION_STATUS_SUCCESSFUL`).
328
+ - **PR #48** — added the `--lang=en-US` Chromium launch arg so the editor UI
329
+ itself stays in English regardless of the user's profile/system language.
330
+ Currently mandatory because the I2V frame-slot labels and parts of
331
+ `ONBOARDING_SELECTORS` / `NEW_PROJECT_SELECTORS` / `SUBMIT_BUTTON_SELECTORS`
332
+ still match by localized text. Dropping `--lang=en-US` is the goal but
333
+ requires invariant capture across the remaining text-matched selectors
334
+ (`scripts/dev/capture_locale_invariants.py` is the diagnostic).
335
+
336
+ **Earlier — Phase 7 multi-image-prompt work** addressed the count-tab selectors:
323
337
  - `_COUNT_TAB_TEXT_RE = ^(1x|x[2-4])$` only matches the digit+x format Flow
324
338
  renders identically in every locale (numbers/symbols are not translated).
325
339
  - `_set_count` falls back to positional `.nth(count - 1)` when the read-back
@@ -343,6 +357,34 @@ in English or Portuguese.
343
357
 
344
358
  ---
345
359
 
360
+ ### `omni-flash` t2v response omits operation name — `flow_operation_id` persists NULL
361
+
362
+ - **Status:** Open · **Severity:** Low · **Affects:** v0.9.0+ (data layer)
363
+
364
+ The data layer's `on_started` callback captures
365
+ `operations[0].operation.name` from each `batchAsyncGenerateVideoText`
366
+ response and persists it as `operations.flow_operation_id`. The
367
+ `omni-flash` model's response shape does not carry that field, so
368
+ omni-flash rows end up with `flow_operation_id` NULL while `veo-*` rows
369
+ carry the expected `operations/...` identifier. The rest of the row
370
+ (prompt, model, aspect, started/completed timestamps, batch ID, output
371
+ paths) is recorded normally.
372
+
373
+ **Impact:** cosmetic for now — `gflow data media <id>` and provenance
374
+ lookup by Flow media ID still work. Any future feature that joins on
375
+ `flow_operation_id` (none in the current CLI) would miss omni-flash
376
+ rows.
377
+
378
+ **Workaround:** none needed if you don't query by `flow_operation_id`.
379
+
380
+ **Roadmap:** capture an `omni-flash` `batchAsyncGenerateVideoText`
381
+ response sample, identify the equivalent provenance handle (if any), and
382
+ either map it into `flow_operation_id` or document that omni-flash
383
+ legitimately has no such identifier. Track via a follow-up issue once a
384
+ sample is captured.
385
+
386
+ ---
387
+
346
388
  ## Mitigated
347
389
 
348
390
  ### Auth verification depends on Google's NextAuth session endpoint
@@ -364,6 +406,23 @@ change surfaces there as a failing test. Start any investigation of a sudden
364
406
 
365
407
  ## Resolved
366
408
 
409
+ ### `gflow image t2i/i2i --model` was a silent no-op on `ui_automation`
410
+
411
+ - **Status:** Resolved · **Severity:** Was-Medium (wrong model = wrong cost + quality, silently) · **Was-affecting:** v0.7.0 through v0.8.1 · **Fixed in:** develop post-v0.8.1 via PR #48 (2026-05-24)
412
+
413
+ Pre-fix, `gflow image t2i --model nano-banana-2` (or any other model) under
414
+ `ui_automation` would set the wire-level model field correctly but **never
415
+ click the model picker in the editor UI**, so Flow used whichever model the
416
+ UI's dropdown was last set to (typically the account default). Users got
417
+ their requested model silently substituted for the default — no error, just
418
+ wrong output and wrong credit cost. Fixed by `_select_image_model` in
419
+ `src/gflow_cli/api/transports/ui_automation.py` which mirrors the new
420
+ `_select_video_model` helper. If you ran `gflow image t2i --model <X>`
421
+ against v0.7.0–v0.8.1 and noticed the output didn't match `<X>`, this is
422
+ why; re-run on the next release (≥ v0.9.0).
423
+
424
+ ---
425
+
367
426
  ### aisandbox-pa generation 401 — bypassed by the `ui_automation` transport
368
427
 
369
428
  - **Status:** Resolved · **Severity:** Was-High (blocked image gen via HTTP transports) · **Fixed in:** v0.7.0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gflow-cli
3
- Version: 0.8.1
3
+ Version: 0.9.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
@@ -58,9 +58,14 @@ Description-Content-Type: text/markdown
58
58
 
59
59
  [![PyPI version](https://img.shields.io/pypi/v/gflow-cli.svg)](https://pypi.org/project/gflow-cli/)
60
60
  [![CI](https://github.com/ffroliva/gflow-cli/actions/workflows/ci.yml/badge.svg)](https://github.com/ffroliva/gflow-cli/actions/workflows/ci.yml)
61
+ [![Release](https://github.com/ffroliva/gflow-cli/actions/workflows/release.yml/badge.svg)](https://github.com/ffroliva/gflow-cli/actions/workflows/release.yml)
61
62
  [![Python versions](https://img.shields.io/pypi/pyversions/gflow-cli.svg)](https://pypi.org/project/gflow-cli/)
62
63
  [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
63
64
  [![Status: alpha](https://img.shields.io/badge/status-alpha-orange.svg)](docs/PROJECT_STATUS.md)
65
+ [![Code style: ruff](https://img.shields.io/badge/code%20style-ruff-000000.svg)](https://github.com/astral-sh/ruff)
66
+ [![Type checked: pyright](https://img.shields.io/badge/type%20checked-pyright-blue.svg)](https://github.com/microsoft/pyright)
67
+ [![Tests: TDD](https://img.shields.io/badge/tests-TDD-brightgreen.svg)](CONTRIBUTING.md)
68
+ [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=ffroliva_gflow-cli&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=ffroliva_gflow-cli)
64
69
 
65
70
  > ⚠️ **Unofficial. Reverse-engineered. Not affiliated with Google.** Endpoints can change at any time. Full [DISCLAIMER](DISCLAIMER.md).
66
71
  >
@@ -70,7 +75,7 @@ Description-Content-Type: text/markdown
70
75
 
71
76
  For Google AI Ultra / Pro subscribers with Veo credits and batch workloads:
72
77
 
73
- - **Burn credits efficiently** — `for p in $(cat prompts.txt); do gflow image t2i "$p"; done` _(image batching ships today; `gflow video i2v` lands in Phase B)_
78
+ - **Burn credits efficiently** — `for p in $(cat prompts.txt); do gflow image t2i "$p"; done` _(image batching, plus `gflow video t2v`/`i2v`/`r2v`, all ship today)_
74
79
  - **Build pipelines** — wire Veo into your content automation, AI video stack, or batch experiments
75
80
  - **Stay in the terminal** — no Chromium UI, no clicking through dialogs (after a one-time `gflow auth login`)
76
81
 
@@ -117,7 +122,7 @@ Reproduce the recording: [`scripts/record_demo.ps1`](scripts/record_demo.ps1) (W
117
122
  | 🎯 **Getting started** | [User Guide](docs/USER_GUIDE.md) · [Usage](docs/USAGE.md) · [Configuration](docs/CONFIGURATION.md) |
118
123
  | 🔐 **Auth & sessions** | [Authentication](docs/AUTHENTICATION.md) · [Known issues](KNOWN_ISSUES.md) |
119
124
  | 🏗️ **Internals** | [Architecture](docs/ARCHITECTURE.md) · [Security](docs/SECURITY.md) · [Debugging](docs/DEBUGGING.md) |
120
- | 📦 **Releases** | [Changelog](CHANGELOG.md) · [Release protocol](RELEASE.md) · [Project status](docs/PROJECT_STATUS.md) |
125
+ | 📦 **Releases** | [Changelog](CHANGELOG.md) · [Roadmap](ROADMAP.md) · [Release protocol](RELEASE.md) · [Project status](docs/PROJECT_STATUS.md) |
121
126
  | 🤝 **Contributing** | [Contributing](CONTRIBUTING.md) · [Development](docs/DEVELOPMENT.md) · [GitHub workflow](docs/GITHUB.md) |
122
127
 
123
128
  ## For AI agents & LLMs
@@ -147,13 +152,13 @@ gflow CLI → Provider (interchangeable) → Flow (ui_automation) / Mock (te
147
152
 
148
153
  **Current transport:** `ui_automation` — drives Flow via a persistent Playwright Chromium profile. Production-stable, end-to-end verified per release (see [LIVE_VERIFICATION_*](docs/) per-release evidence files).
149
154
 
150
- **What's blocked:** A pure HTTP transport for video generation. The video upload endpoint returns HTTP 401 under non-Chrome browsers + a reCAPTCHA mint we cannot reproduce headlessly. Three earlier HTTP strategies (`evaluate_fetch` / `bearer` / `sapisidhash`) are named in the codebase history; the actual transport modules have not yet been extracted into a subpackage.
155
+ **What's blocked:** A pure HTTP transport for video generation. The video upload endpoint returns HTTP 401 under non-Chrome browsers + a reCAPTCHA mint we cannot reproduce headlessly. Three earlier HTTP strategies (`evaluate_fetch` / `bearer` / `sapisidhash`) live under `src/gflow_cli/api/transports/experimental/` they are importable for research but not on the production critical path.
151
156
 
152
157
  **How you can help:** If you have successfully driven `aisandbox-pa.googleapis.com` from outside a real Chrome session — or have insight into Google's anti-bot stack here — please open an issue. A working REST transport would unlock serverless deployments, true horizontal concurrency, and roughly 10× the project's reach. Details: [docs/ARCHITECTURE.md § Headed-browser dependency](docs/ARCHITECTURE.md#headed-browser-dependency--current-limitation).
153
158
 
154
159
  ## Project status
155
160
 
156
- **v0.8.1 — alpha (docs refresh).** Image (T2I / I2I / upload) + Video T2V live end-to-end on `ui_automation`. Video I2V + batch are queued for Phase B. Full milestone history → [docs/PROJECT_STATUS.md](docs/PROJECT_STATUS.md). Changelog → [CHANGELOG.md](CHANGELOG.md).
161
+ **v0.9.0 — alpha.** Image (T2I / I2I / upload) + Video T2V / I2V / R2V live end-to-end on `ui_automation`, with a video `--model` picker (5 Veo models) + `--duration` / `--count`. New in v0.9.0: `gflow data list {projects,images,videos,profiles}` read CLI over the local SQLite catalog, `ROADMAP.md`, and locale-agnostic media-dialog selectors that fix non-English Chrome profiles. Only video `batch` (manifest runner) is still queued for Phase B — use a shell for-loop until then ([USAGE](docs/USAGE.md#gflow-video-batch)). Full milestone history → [docs/PROJECT_STATUS.md](docs/PROJECT_STATUS.md). Changelog → [CHANGELOG.md](CHANGELOG.md). Where the project is heading → [ROADMAP.md](ROADMAP.md).
157
162
 
158
163
  ## License & legal
159
164
 
@@ -167,4 +172,15 @@ gflow CLI → Provider (interchangeable) → Flow (ui_automation) / Mock (te
167
172
 
168
173
  ---
169
174
 
175
+ ## Stats
176
+
177
+ [![GitHub stars](https://img.shields.io/github/stars/ffroliva/gflow-cli?style=social)](https://github.com/ffroliva/gflow-cli/stargazers)
178
+ [![GitHub forks](https://img.shields.io/github/forks/ffroliva/gflow-cli?style=social)](https://github.com/ffroliva/gflow-cli/network/members)
179
+ [![GitHub watchers](https://img.shields.io/github/watchers/ffroliva/gflow-cli?style=social)](https://github.com/ffroliva/gflow-cli/watchers)
180
+ [![GitHub issues](https://img.shields.io/github/issues/ffroliva/gflow-cli)](https://github.com/ffroliva/gflow-cli/issues)
181
+ [![GitHub pull requests](https://img.shields.io/github/issues-pr/ffroliva/gflow-cli)](https://github.com/ffroliva/gflow-cli/pulls)
182
+ [![GitHub last commit](https://img.shields.io/github/last-commit/ffroliva/gflow-cli)](https://github.com/ffroliva/gflow-cli/commits/main)
183
+ [![GitHub repo size](https://img.shields.io/github/repo-size/ffroliva/gflow-cli)](https://github.com/ffroliva/gflow-cli)
184
+ [![PyPI downloads](https://img.shields.io/pypi/dm/gflow-cli.svg)](https://pypi.org/project/gflow-cli/)
185
+
170
186
  If `gflow-cli` saves you time, please ⭐ the repo — it is the cheapest way to support the project.
@@ -2,7 +2,7 @@
2
2
 
3
3
  > **Status:** Living document. Updated as phases complete.
4
4
  > **Owner:** [@ffroliva](https://github.com/ffroliva)
5
- > **Last revised:** 2026-05-16 (v0.6.0a5Bug A/B transport fixes + issue-tracked work)
5
+ > **Last revised:** 2026-05-24 (developpost-PR #48 i2v/r2v/model-picker, PR #51 locale env-override)
6
6
 
7
7
  This plan turns the v0.1 scaffold into a production-grade CLI for Google AI Ultra/Pro subscribers who want to spend their Flow credits via batch automation. The plan is opinionated, treating this repo as a portfolio-grade benchmark.
8
8
 
@@ -91,6 +91,13 @@ src/gflow_cli/
91
91
  ├── observability.py ← Phase 4 — structlog bootstrap + event emitters
92
92
  ├── paths.py ← XDG-aware default paths
93
93
  ├── profile_store.py ← profile inventory + default-profile config.toml
94
+ ├── data/ ← Phase 6 — local SQLite provenance layer
95
+ │ ├── __init__.py
96
+ │ ├── store.py ← DataStore (connection + migration runner)
97
+ │ ├── repository.py ← read queries (get_by_media_id, list_by_profile, …)
98
+ │ ├── recorder.py ← OperationRecorder (write path + redact_metadata)
99
+ │ └── migrations/
100
+ │ └── 0001_initial.sql
94
101
  └── api/
95
102
  ├── __init__.py
96
103
  ├── _retry.py ← Phase 4 — tenacity AsyncRetrying + Retry-After cap
@@ -108,7 +115,7 @@ src/gflow_cli/
108
115
 
109
116
  Documented in [docs/CONFIGURATION.md](docs/CONFIGURATION.md) and [.env.template](.env.template). Variables:
110
117
 
111
- `GFLOW_CLI_HOME`, `GFLOW_CLI_OUTPUT_DIR`, `GFLOW_CLI_PROFILE`, `GFLOW_CLI_PROVIDER`, `GFLOW_CLI_GEMINI_API_KEY`, `GFLOW_CLI_TIMEOUT_SECONDS`, `GFLOW_CLI_LOG_LEVEL`, `GFLOW_CLI_LOG_FORMAT`, `GFLOW_CLI_CONCURRENCY`.
118
+ `GFLOW_CLI_HOME`, `GFLOW_CLI_OUTPUT_DIR`, `GFLOW_CLI_PROFILE`, `GFLOW_CLI_PROVIDER`, `GFLOW_CLI_GEMINI_API_KEY`, `GFLOW_CLI_TIMEOUT_SECONDS`, `GFLOW_CLI_LOG_LEVEL`, `GFLOW_CLI_LOG_FORMAT`, `GFLOW_CLI_CONCURRENCY`, `GFLOW_CLI_DB_PATH`, `GFLOW_CLI_HISTORY_PROMPTS`.
112
119
 
113
120
  Default paths via `platformdirs`:
114
121
 
@@ -339,7 +346,14 @@ The video-generation feature has its own sub-phase plan (spike → Phase A → P
339
346
  - ⚠️ Q7 — status poll `page.request.post` → 401; the spec §5.5 polling design must be reworked in Phase A (capture Flow's own status responses).
340
347
  - ⏭️ Q1 / Q3 / Q6 — image attachment is an in-page catalog dialog; driving it, the start-only-I2V check, and the R2V slot cap are deferred to Phase B.
341
348
 
342
- **Next:** Phase A (T2V transport), once §5.5 is revised for the Q7 401. GitHub issue #24 tracks making the transport selectors language-agnostic.
349
+ **Next:** Phase A (T2V transport), once §5.5 is revised for the Q7 401. Issue #24 (locale-agnostic selectors): Phase 1 (env override via `GFLOW_CLI_LOCALE`) landed via PR #51 on develop 2026-05-24 (post-v0.8.1, unreleased); live-verified end-to-end in pt-BR (1 credit, mp4 downloaded). Full removal of the `--lang=en-US` Chromium arg is gated on a selector-invariant capture across the remaining onboarding/new-project text selectors.
350
+
351
+ ---
352
+
353
+ ### Phase 7 — Protocol Extensions (v0.8.1, 2026-05-23)
354
+
355
+ - [~] **Issue #24: Locale-Agnostic Selectors — Phase 1 shipped, Phase 2 pending.** PR #51 (develop, 2026-05-24, post-v0.8.1) added the `GFLOW_CLI_LOCALE` env override on Playwright's launch `locale=` parameter, and live-verified `gflow video t2v` end-to-end under `pt-BR`. Some selectors are already locale-invariant (count tabs use `^(1x|x[2-4])$`, video aspect/duration use id-suffix + icon ligatures from PR #48); others — notably `ONBOARDING_SELECTORS`, parts of `NEW_PROJECT_SELECTORS` / `SUBMIT_BUTTON_SELECTORS`, and the I2V frame-slot text labels — are still localized and currently rely on the `--lang=en-US` Chromium launch arg added by PR #48. Tracked under [KNOWN_ISSUES § issue #24](KNOWN_ISSUES.md). Dropping `--lang=en-US` requires invariant capture across the remaining text selectors.
356
+ - [ ] **Model Context Protocol (MCP) Server.** (Backlog) Expose core gflow-cli tools via MCP for language-agnostic agentic access.
343
357
 
344
358
  ---
345
359
 
@@ -578,17 +592,22 @@ gates on the same header.
578
592
 
579
593
  ---
580
594
 
581
- ### Phase 6 — Operations history & cost tracking BACKLOG
595
+ ### Phase 6 — Local SQLite data layerIMPLEMENTED (PR #TBD)
596
+
597
+ Records new image, batch, and T2V provenance in a local SQLite database. Read-only `gflow data media <id>` command exposed.
598
+
599
+ - `gflow_cli/data/` — `DataStore` + repository + `OperationRecorder` + `redact_metadata`
600
+ - Default DB path: `<GFLOW_CLI_HOME>/gflow.db`; override via `GFLOW_CLI_DB_PATH`
601
+ - Schema versioned via SHA-256-checksummed migrations (`0001_initial.sql`); newer-schema detection raises `DataStoreError` (exit 16) with a clear upgrade hint
602
+ - Privacy: `GFLOW_CLI_HISTORY_PROMPTS=redacted` stores only SHA-256 prompt hash; signed CDN URLs, reCAPTCHA tokens, and auth headers are stripped by `redact_metadata` before any DB write
603
+ - `gflow data media <id> [--profile]` prints profile, media ID, project ID, kind, and local file paths
604
+ - T2V now flows through `FlowApiClient.generate_video`, sharing the client boundary with image commands
582
605
 
583
- Foundation laid by Phase 4's structured `error_raised` events + Problem Details. Phase 6 adds a local persistence layer so users can answer "what did I generate last week and what did it cost?".
606
+ **Backlog follow-ons (not in this PR):**
584
607
 
585
- - Local SQLite (or DuckDB if analytical queries dominate) at `$GFLOW_CLI_HOME/operations.db`
586
- - Schema: `operations(id, timestamp, profile, cli_command, project_id, media_uuids, prompt, model, aspect, seed_count, status, error_class, error_problem, duration_ms, output_paths)` every CLI invocation appends one row
587
- - Schema versioned via Alembic-style migrations
588
- - New CLI: `gflow history list/show/search` — query operations by date / profile / command / status
589
- - Cost tracking: best-effort credit estimation per call (Veo 3.1 ≈ X credits/sec, Imagen ≈ Y credits/image — tabulate from observation)
590
- - Privacy: prompts are user-generated content; persist locally only, never transmit
591
- - Out of scope until Phase 6 ships: cloud sync, multi-user history
608
+ - `gflow data import` / `gflow data repair` back-fill older operations not recorded by this version
609
+ - Richer management UI: `gflow data list`, `gflow data search`, cost/credit estimation
610
+ - `gflow history` alias for the data subcommand
592
611
 
593
612
  ### CDP Attach Transport — BACKLOG (deferred)
594
613
 
@@ -4,9 +4,14 @@
4
4
 
5
5
  [![PyPI version](https://img.shields.io/pypi/v/gflow-cli.svg)](https://pypi.org/project/gflow-cli/)
6
6
  [![CI](https://github.com/ffroliva/gflow-cli/actions/workflows/ci.yml/badge.svg)](https://github.com/ffroliva/gflow-cli/actions/workflows/ci.yml)
7
+ [![Release](https://github.com/ffroliva/gflow-cli/actions/workflows/release.yml/badge.svg)](https://github.com/ffroliva/gflow-cli/actions/workflows/release.yml)
7
8
  [![Python versions](https://img.shields.io/pypi/pyversions/gflow-cli.svg)](https://pypi.org/project/gflow-cli/)
8
9
  [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
9
10
  [![Status: alpha](https://img.shields.io/badge/status-alpha-orange.svg)](docs/PROJECT_STATUS.md)
11
+ [![Code style: ruff](https://img.shields.io/badge/code%20style-ruff-000000.svg)](https://github.com/astral-sh/ruff)
12
+ [![Type checked: pyright](https://img.shields.io/badge/type%20checked-pyright-blue.svg)](https://github.com/microsoft/pyright)
13
+ [![Tests: TDD](https://img.shields.io/badge/tests-TDD-brightgreen.svg)](CONTRIBUTING.md)
14
+ [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=ffroliva_gflow-cli&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=ffroliva_gflow-cli)
10
15
 
11
16
  > ⚠️ **Unofficial. Reverse-engineered. Not affiliated with Google.** Endpoints can change at any time. Full [DISCLAIMER](DISCLAIMER.md).
12
17
  >
@@ -16,7 +21,7 @@
16
21
 
17
22
  For Google AI Ultra / Pro subscribers with Veo credits and batch workloads:
18
23
 
19
- - **Burn credits efficiently** — `for p in $(cat prompts.txt); do gflow image t2i "$p"; done` _(image batching ships today; `gflow video i2v` lands in Phase B)_
24
+ - **Burn credits efficiently** — `for p in $(cat prompts.txt); do gflow image t2i "$p"; done` _(image batching, plus `gflow video t2v`/`i2v`/`r2v`, all ship today)_
20
25
  - **Build pipelines** — wire Veo into your content automation, AI video stack, or batch experiments
21
26
  - **Stay in the terminal** — no Chromium UI, no clicking through dialogs (after a one-time `gflow auth login`)
22
27
 
@@ -63,7 +68,7 @@ Reproduce the recording: [`scripts/record_demo.ps1`](scripts/record_demo.ps1) (W
63
68
  | 🎯 **Getting started** | [User Guide](docs/USER_GUIDE.md) · [Usage](docs/USAGE.md) · [Configuration](docs/CONFIGURATION.md) |
64
69
  | 🔐 **Auth & sessions** | [Authentication](docs/AUTHENTICATION.md) · [Known issues](KNOWN_ISSUES.md) |
65
70
  | 🏗️ **Internals** | [Architecture](docs/ARCHITECTURE.md) · [Security](docs/SECURITY.md) · [Debugging](docs/DEBUGGING.md) |
66
- | 📦 **Releases** | [Changelog](CHANGELOG.md) · [Release protocol](RELEASE.md) · [Project status](docs/PROJECT_STATUS.md) |
71
+ | 📦 **Releases** | [Changelog](CHANGELOG.md) · [Roadmap](ROADMAP.md) · [Release protocol](RELEASE.md) · [Project status](docs/PROJECT_STATUS.md) |
67
72
  | 🤝 **Contributing** | [Contributing](CONTRIBUTING.md) · [Development](docs/DEVELOPMENT.md) · [GitHub workflow](docs/GITHUB.md) |
68
73
 
69
74
  ## For AI agents & LLMs
@@ -93,13 +98,13 @@ gflow CLI → Provider (interchangeable) → Flow (ui_automation) / Mock (te
93
98
 
94
99
  **Current transport:** `ui_automation` — drives Flow via a persistent Playwright Chromium profile. Production-stable, end-to-end verified per release (see [LIVE_VERIFICATION_*](docs/) per-release evidence files).
95
100
 
96
- **What's blocked:** A pure HTTP transport for video generation. The video upload endpoint returns HTTP 401 under non-Chrome browsers + a reCAPTCHA mint we cannot reproduce headlessly. Three earlier HTTP strategies (`evaluate_fetch` / `bearer` / `sapisidhash`) are named in the codebase history; the actual transport modules have not yet been extracted into a subpackage.
101
+ **What's blocked:** A pure HTTP transport for video generation. The video upload endpoint returns HTTP 401 under non-Chrome browsers + a reCAPTCHA mint we cannot reproduce headlessly. Three earlier HTTP strategies (`evaluate_fetch` / `bearer` / `sapisidhash`) live under `src/gflow_cli/api/transports/experimental/` they are importable for research but not on the production critical path.
97
102
 
98
103
  **How you can help:** If you have successfully driven `aisandbox-pa.googleapis.com` from outside a real Chrome session — or have insight into Google's anti-bot stack here — please open an issue. A working REST transport would unlock serverless deployments, true horizontal concurrency, and roughly 10× the project's reach. Details: [docs/ARCHITECTURE.md § Headed-browser dependency](docs/ARCHITECTURE.md#headed-browser-dependency--current-limitation).
99
104
 
100
105
  ## Project status
101
106
 
102
- **v0.8.1 — alpha (docs refresh).** Image (T2I / I2I / upload) + Video T2V live end-to-end on `ui_automation`. Video I2V + batch are queued for Phase B. Full milestone history → [docs/PROJECT_STATUS.md](docs/PROJECT_STATUS.md). Changelog → [CHANGELOG.md](CHANGELOG.md).
107
+ **v0.9.0 — alpha.** Image (T2I / I2I / upload) + Video T2V / I2V / R2V live end-to-end on `ui_automation`, with a video `--model` picker (5 Veo models) + `--duration` / `--count`. New in v0.9.0: `gflow data list {projects,images,videos,profiles}` read CLI over the local SQLite catalog, `ROADMAP.md`, and locale-agnostic media-dialog selectors that fix non-English Chrome profiles. Only video `batch` (manifest runner) is still queued for Phase B — use a shell for-loop until then ([USAGE](docs/USAGE.md#gflow-video-batch)). Full milestone history → [docs/PROJECT_STATUS.md](docs/PROJECT_STATUS.md). Changelog → [CHANGELOG.md](CHANGELOG.md). Where the project is heading → [ROADMAP.md](ROADMAP.md).
103
108
 
104
109
  ## License & legal
105
110
 
@@ -113,4 +118,15 @@ gflow CLI → Provider (interchangeable) → Flow (ui_automation) / Mock (te
113
118
 
114
119
  ---
115
120
 
121
+ ## Stats
122
+
123
+ [![GitHub stars](https://img.shields.io/github/stars/ffroliva/gflow-cli?style=social)](https://github.com/ffroliva/gflow-cli/stargazers)
124
+ [![GitHub forks](https://img.shields.io/github/forks/ffroliva/gflow-cli?style=social)](https://github.com/ffroliva/gflow-cli/network/members)
125
+ [![GitHub watchers](https://img.shields.io/github/watchers/ffroliva/gflow-cli?style=social)](https://github.com/ffroliva/gflow-cli/watchers)
126
+ [![GitHub issues](https://img.shields.io/github/issues/ffroliva/gflow-cli)](https://github.com/ffroliva/gflow-cli/issues)
127
+ [![GitHub pull requests](https://img.shields.io/github/issues-pr/ffroliva/gflow-cli)](https://github.com/ffroliva/gflow-cli/pulls)
128
+ [![GitHub last commit](https://img.shields.io/github/last-commit/ffroliva/gflow-cli)](https://github.com/ffroliva/gflow-cli/commits/main)
129
+ [![GitHub repo size](https://img.shields.io/github/repo-size/ffroliva/gflow-cli)](https://github.com/ffroliva/gflow-cli)
130
+ [![PyPI downloads](https://img.shields.io/pypi/dm/gflow-cli.svg)](https://pypi.org/project/gflow-cli/)
131
+
116
132
  If `gflow-cli` saves you time, please ⭐ the repo — it is the cheapest way to support the project.
@@ -0,0 +1,45 @@
1
+ # Roadmap
2
+
3
+ > Themes, not deadlines. `gflow-cli` is an unofficial CLI tracking a private Google Flow API — a single upstream UI change can rearrange a sprint, so we publish themed milestones with deliverables and let velocity emerge.
4
+
5
+ ## v0.9.0 — Maturity & Visibility (current)
6
+
7
+ The release that makes the underlying data layer visible to the user. Adds `gflow data list` for read-only catalog browsing, publishes this roadmap, wires sponsorship, and refreshes the documentation surface to reflect everything that shipped through v0.8.x.
8
+
9
+ - Local SQLite catalog (shipped in PR #58, surfaced here)
10
+ - `gflow video t2v` model picker (`omni-flash` / `veo-lite` / `veo-fast` / `veo-quality` / `veo-lite-lp`)
11
+ - `gflow video i2v` — image-to-video with optional end frame
12
+ - `gflow video r2v` — reference-to-video (Flow ingredients)
13
+ - `gflow data list {projects,images,videos,profiles}` — read-only catalog query
14
+ - Locale-agnostic media-dialog selectors (fixes non-English Chrome profiles)
15
+ - `ROADMAP.md` (sponsorship wiring deferred to a follow-up patch release)
16
+
17
+ ## v0.10.0 — Data Query Surface
18
+
19
+ Extends the data layer surface from read-only listing to inspection and selective export. Same local SQLite catalog, richer ways to interrogate it.
20
+
21
+ - `gflow data show <media_id>` — full record for one image / video / project
22
+ - `gflow data search` — filter by prompt substring, model, aspect, date range
23
+ - `gflow data export` — JSON / CSV / TSV
24
+ - `gflow data prune` — retention controls (`--older-than`, `--keep-last-n`)
25
+
26
+ ## v0.11.0 — Local HTTP API + Web UI
27
+
28
+ The API and the UI ship together as one deliverable — neither is useful alone. `gflow ui` boots a local HTTP server on `127.0.0.1` that hosts both the API and the UI; everything stays loopback-only.
29
+
30
+ - `gflow ui` — single command, single port
31
+ - Local REST API over the SQLite catalog with read endpoints for projects / images / videos / profiles
32
+ - Web UI consumes the API; browses generations with thumbnails
33
+ - Aggregated view across local profiles (read-only)
34
+
35
+ ## v1.0.0 — Stable API
36
+
37
+ The point at which `FlowApiClient` carries a SemVer commitment and the documentation reaches "production-ready" standard.
38
+
39
+ - `FlowApiClient` SemVer commitment
40
+ - HTTP transport revival path (community-contrib; if feasible)
41
+ - Production-ready documentation
42
+
43
+ ---
44
+
45
+ *Themes, not deadlines. An unofficial CLI tracking a private API can have its sprint broken by a single UI change upstream — fixed dates would be dishonest.*
@@ -38,7 +38,7 @@ The hexagonal target above is the steady state. The **current** package — and
38
38
 
39
39
  **Per-module rules:**
40
40
 
41
- - Each top-level package or file under `src/gflow_cli/` is a module with one clear domain (`auth`, `api`, `cli`, `errors`, `observability`, `manifest`, `paths`, `config`, `profile_store`).
41
+ - Each top-level package or file under `src/gflow_cli/` is a module with one clear domain (`auth`, `api`, `cli`, `errors`, `observability`, `manifest`, `paths`, `config`, `profile_store`, `data`).
42
42
  - Each module exposes a public interface via `__init__.py` and (where applicable) explicit `__all__`.
43
43
  - Internals are prefixed with `_` (single leading underscore) and never imported across modules.
44
44
  - Cross-module communication goes through public interfaces, never private internals.
@@ -50,6 +50,10 @@ The hexagonal target above is the steady state. The **current** package — and
50
50
  - `gflow_cli.errors` — exception taxonomy aligned with [RFC 9457 Problem Details](https://datatracker.ietf.org/doc/html/rfc9457). Each `GFlowError` subclass carries `type` (URI), `title`, `status`, `detail`, `instance`, `remediation_hint`. The `to_problem_details()` method serializes to the RFC 9457 JSON shape and is the stable contract for telemetry consumers.
51
51
  - `gflow_cli.observability` — structlog configuration + the `error_raised` event emitter. This is the future home for metrics + tracing (Phase 5+) too.
52
52
 
53
+ **Data layer module (shipped in v0.9.0):**
54
+
55
+ - `gflow_cli/data/` — local SQLite persistence layer (`DataStore` + `DataRepository` + `OperationRecorder` + redaction + read-only `queries` for `gflow data list`). Records all new image/video operations, asset provenance, and local file metadata. Default DB path is resolved from `$GFLOW_CLI_DB_PATH` (default: `~/.local/share/gflow-cli/data.db` on POSIX, the equivalent platformdirs user-data dir on Windows). Migrations versioned via SHA-256 checksums; safe forward-only semantics with newer-schema detection. T2V now flows through `FlowApiClient.generate_video`, sharing the client boundary with image commands.
56
+
53
57
  **Why RFC 9457 for errors:** Problem Details is the IETF-standard shape for machine-readable HTTP error responses. Even though gflow-cli is a CLI (not an HTTP server), adopting the same vocabulary means: (a) the error log shape is greppable by stable `type` URI, (b) future cloud-edge integrations (e.g., a `gflow serve` HTTP front-end) can return our errors directly without translation, (c) downstream telemetry tools recognize the shape immediately.
54
58
 
55
59
  **Phase 4 does NOT:**
@@ -109,6 +109,31 @@ GFLOW_CLI_AUTH_LOGIN_TIMEOUT=120 gflow auth login # abort after 2 minutes
109
109
  **Recommended starting point:** `4`. Each Page costs ~30–60 MiB of memory on Chromium headless; don't exceed `8` without measuring resident-set size. Cookies and storage state are shared at Context level, so every Page inherits the signed-in profile for free.
110
110
  **Shipped in:** v0.4.0a2.
111
111
 
112
+ ### `GFLOW_CLI_DB_PATH`
113
+
114
+ **What:** Override the path to the local SQLite operations database.
115
+ **Default:** `<GFLOW_CLI_HOME>/gflow.db`
116
+ **Override examples:**
117
+ ```bash
118
+ export GFLOW_CLI_DB_PATH=/secure-volume/gflow.db # POSIX
119
+ $env:GFLOW_CLI_DB_PATH = "D:\gflow-data\gflow.db" # PowerShell
120
+ ```
121
+
122
+ Use this when you want the DB on a different volume, outside `GFLOW_CLI_HOME`, or when running multiple isolated environments that share the same home dir.
123
+
124
+ ### `GFLOW_CLI_HISTORY_PROMPTS`
125
+
126
+ **What:** Controls how prompt text is persisted in the local database.
127
+ **Values:**
128
+ - `store` (default) — the full prompt text is saved to the database alongside the operation record.
129
+ - `redacted` — only the SHA-256 hash of the prompt is stored; the prompt text itself is never written to disk. Use this when prompts may contain sensitive content.
130
+
131
+ **Default:** `store`
132
+
133
+ ```bash
134
+ GFLOW_CLI_HISTORY_PROMPTS=redacted gflow image t2i "confidential brief"
135
+ ```
136
+
112
137
  ### `GFLOW_CLI_HEADLESS`
113
138
 
114
139
  **What:** Run Playwright in headless mode for non-`auth login` commands.
@@ -116,6 +141,15 @@ GFLOW_CLI_AUTH_LOGIN_TIMEOUT=120 gflow auth login # abort after 2 minutes
116
141
  **Default:** `true`
117
142
  **When to flip to `false`:** if reCAPTCHA Enterprise refuses to mint tokens (Google's bot-detection sometimes refuses headless Chromium but accepts a visible window). Set to `false` and re-run; the browser will appear during generation but the session is still reused from the persistent profile.
118
143
 
144
+ ### `GFLOW_CLI_LOCALE`
145
+
146
+ **What:** BCP-47 locale tag passed to Playwright's `launch_persistent_context(locale=...)` — controls the `Accept-Language` HTTP header only.
147
+ **Values:** any BCP-47 tag (e.g. `en-US`, `pt-BR`, `es-ES`, `ja-JP`)
148
+ **Default:** `en-US`
149
+ **Shipped in:** post-v0.8.1 develop (PR #51).
150
+ **When to set it:** capturing locale-invariant DOM via `scripts/dev/capture_locale_invariants.py`, or live-verifying a generation under a non-EN account language.
151
+ **Important:** Chrome's *UI* language is independently forced to `en-US` via the `--lang=en-US` launch arg (so Flow keeps serving `/fx/tools/flow/` and the editor's localized text selectors keep working). This env var only affects request headers — not the editor UI you see. See [KNOWN_ISSUES § issue #24](../KNOWN_ISSUES.md) for the path to dropping `--lang=en-US`.
152
+
119
153
  ## Output paths
120
154
 
121
155
  The default output scheme keeps generated assets sortable, dated, and grouped by job: