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.
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/.env.template +9 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/AGENTS.md +2 -2
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/CHANGELOG.md +122 -1
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/KNOWN_ISSUES.md +60 -1
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/PKG-INFO +21 -5
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/PLAN.md +31 -12
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/README.md +20 -4
- gflow_cli-0.9.0/ROADMAP.md +45 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/ARCHITECTURE.md +5 -1
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/CONFIGURATION.md +34 -0
- gflow_cli-0.9.0/docs/DATA_LAYER.md +399 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/INDEX.md +9 -1
- gflow_cli-0.9.0/docs/LIVE_VERIFICATION_data_layer.md +209 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/LIVE_VERIFICATION_v0.8.1.md +28 -21
- gflow_cli-0.9.0/docs/LIVE_VERIFICATION_v0.9.0.md +107 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/LIVE_VERIFICATION_video_download.md +5 -3
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/PROJECT_STATUS.md +13 -2
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/SECURITY.md +33 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/USAGE.md +148 -36
- gflow_cli-0.9.0/docs/superpowers/notes/v0.9.0-schema-reconciliation.md +108 -0
- gflow_cli-0.9.0/docs/superpowers/plans/2026-05-23-locale-agnostic-selectors.md +108 -0
- gflow_cli-0.9.0/docs/superpowers/plans/2026-05-24-data-layer.md +2452 -0
- gflow_cli-0.9.0/docs/superpowers/plans/2026-05-24-v0.9.0-release-implementation.md +2123 -0
- gflow_cli-0.9.0/docs/superpowers/specs/2026-05-23-locale-agnostic-selectors.md +66 -0
- gflow_cli-0.9.0/docs/superpowers/specs/2026-05-23-readme-v0.8.1-refresh-design.md +359 -0
- gflow_cli-0.9.0/docs/superpowers/specs/2026-05-24-data-layer-design.md +403 -0
- gflow_cli-0.9.0/docs/superpowers/specs/2026-05-24-v0.9.0-release-design.md +204 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/llms.txt +3 -1
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/pyproject.toml +1 -1
- gflow_cli-0.9.0/scripts/dev/capture_image_add_media_dom.py +184 -0
- gflow_cli-0.9.0/scripts/dev/capture_locale_invariants.py +87 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/src/gflow_cli/__init__.py +1 -1
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/src/gflow_cli/api/client.py +99 -30
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/src/gflow_cli/api/dto.py +2 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/src/gflow_cli/api/image.py +5 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/src/gflow_cli/api/transports/_common.py +16 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/src/gflow_cli/api/transports/base.py +25 -1
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/src/gflow_cli/api/transports/ui_automation.py +82 -15
- gflow_cli-0.9.0/src/gflow_cli/api/transports/ui_automation_video.py +1013 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/src/gflow_cli/api/video.py +124 -5
- gflow_cli-0.9.0/src/gflow_cli/auth/internal_chromium.py +158 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/src/gflow_cli/auth/real_chrome.py +80 -67
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/src/gflow_cli/browser_manager.py +10 -19
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/src/gflow_cli/cli.py +2 -0
- gflow_cli-0.9.0/src/gflow_cli/cli_data.py +299 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/src/gflow_cli/cli_image.py +257 -159
- gflow_cli-0.9.0/src/gflow_cli/cli_video.py +464 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/src/gflow_cli/config.py +19 -0
- gflow_cli-0.9.0/src/gflow_cli/data/__init__.py +5 -0
- gflow_cli-0.9.0/src/gflow_cli/data/migrations/0001_initial.sql +100 -0
- gflow_cli-0.9.0/src/gflow_cli/data/migrations/__init__.py +1 -0
- gflow_cli-0.9.0/src/gflow_cli/data/models.py +179 -0
- gflow_cli-0.9.0/src/gflow_cli/data/queries.py +326 -0
- gflow_cli-0.9.0/src/gflow_cli/data/recorder.py +407 -0
- gflow_cli-0.9.0/src/gflow_cli/data/redaction.py +48 -0
- gflow_cli-0.9.0/src/gflow_cli/data/repository.py +585 -0
- gflow_cli-0.9.0/src/gflow_cli/data/store.py +239 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/src/gflow_cli/errors.py +32 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/src/gflow_cli/exceptions.py +3 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/src/gflow_cli/image_batch.py +105 -20
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/src/gflow_cli/paths.py +5 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/api/test_client.py +60 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/api/test_concurrency.py +27 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/api/test_video.py +80 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/api/transports/test_common.py +16 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/api/transports/test_ui_automation.py +43 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/api/transports/test_ui_automation_video.py +118 -6
- gflow_cli-0.9.0/tests/cli/test_cli_data.py +81 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/cli/test_cli_image.py +208 -18
- gflow_cli-0.9.0/tests/cli/test_cli_video.py +208 -0
- gflow_cli-0.9.0/tests/data/test_packaging.py +30 -0
- gflow_cli-0.9.0/tests/data/test_recorder.py +155 -0
- gflow_cli-0.9.0/tests/data/test_redaction.py +31 -0
- gflow_cli-0.9.0/tests/data/test_repository.py +272 -0
- gflow_cli-0.9.0/tests/data/test_settings_and_errors.py +47 -0
- gflow_cli-0.9.0/tests/data/test_store_migrations.py +114 -0
- gflow_cli-0.9.0/tests/e2e/test_data_layer_e2e.py +439 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/e2e/test_transports_e2e.py +66 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/features/test_image_steps.py +1 -0
- gflow_cli-0.9.0/tests/fixtures/seeded_catalog.py +226 -0
- gflow_cli-0.9.0/tests/image_batch/__init__.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/image_batch/test_image_manifest.py +222 -1
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/image_batch/test_observability_events.py +78 -0
- gflow_cli-0.9.0/tests/smoke/__init__.py +0 -0
- gflow_cli-0.9.0/tests/test_cli_data.py +147 -0
- gflow_cli-0.9.0/tests/test_data_queries.py +151 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/test_errors.py +2 -2
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/uv.lock +1 -1
- gflow_cli-0.8.1/src/gflow_cli/api/transports/ui_automation_video.py +0 -543
- gflow_cli-0.8.1/src/gflow_cli/auth/internal_chromium.py +0 -147
- gflow_cli-0.8.1/src/gflow_cli/cli_video.py +0 -153
- gflow_cli-0.8.1/tests/cli/test_cli_video.py +0 -68
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/.claude/README.md +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/.claude/commands/gflow/changelog.md +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/.claude/commands/gflow/check.md +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/.claude/commands/gflow/doc-review.md +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/.claude/commands/gflow/known-issues.md +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/.claude/commands/gflow/plan.md +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/.claude/commands/gflow/release.md +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/.continue-here.md +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/.gitattributes +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/.github/CODEOWNERS +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/.github/copilot-instructions.md +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/.github/dependabot.yml +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/.github/workflows/ci.yml +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/.github/workflows/external-pr-triage.yml +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/.github/workflows/release.yml +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/.gitignore +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/.gitleaks.toml +0 -0
- {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
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/.planning/todos/pending/pr-38-review.md +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/.pre-commit-config.yaml +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/.secrets.baseline +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/CLAUDE.md +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/CONFIGURATION.md +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/CONTRIBUTING.md +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/DISCLAIMER.md +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/LICENSE +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/RELEASE.md +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/AGENT_GUIDE.md +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/AUTHENTICATION.md +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/DEBUGGING.md +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/DEVELOPMENT.md +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/GITHUB.md +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/LIVE_VERIFICATION_image_batch.md +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/LIVE_VERIFICATION_v0.7.0.md +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/USER_GUIDE.md +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/assets/example-run.gif +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/2026-05-17-issue-15-handover.md +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/plans/2026-05-09-image-mvp-orchestration.md +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/plans/2026-05-09-image-mvp.md +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/plans/2026-05-09-video-mvp-orchestration.md +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/plans/2026-05-09-video-mvp.md +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/plans/2026-05-10-phase-4-hardening-orchestration.md +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/plans/2026-05-10-phase-4-hardening.md +0 -0
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/plans/2026-05-14-shell-multi-prompt/PLAN.md +0 -0
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {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
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/plans/2026-05-15-auth-login-real-chrome/PLAN.md +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/plans/2026-05-15-auth-login-real-chrome/orchestration.md +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/plans/2026-05-17-e2e-test-coverage.md +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/plans/2026-05-17-issue-15-auth-verification-fix.md +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/plans/2026-05-17-issue-15-i2v-bearer-auth.md +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/plans/2026-05-17-issue-15-orchestration.md +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/plans/2026-05-18-video-phase0-submit-spike.md +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/plans/2026-05-19-video-phase-a-execution-state.md +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/plans/2026-05-19-video-phase-a-orchestration.md +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/plans/2026-05-19-video-phase-a-t2v.md +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/plans/2026-05-20-video-download-t2v-cli.md +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/plans/2026-05-21-multi-image-prompt-orchestration.md +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/plans/2026-05-21-multi-image-prompt.md +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/plans/2026-05-22-pr-38-review.md +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/plans/2026-05-22-stay-mounted-batch-session-plan.md +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/specs/2026-05-10-phase-4-hardening-design.md +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/specs/2026-05-14-shell-multi-prompt-design.md +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/specs/2026-05-15-auth-login-real-chrome-design.md +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/specs/2026-05-17-e2e-test-coverage-design.md +0 -0
- {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
- {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
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/specs/2026-05-17-issue-15-root-cause-findings.md +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/specs/2026-05-18-ui-automation-video-generation-design.md +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/specs/2026-05-21-multi-image-prompt-design.md +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/specs/2026-05-22-pr-38-review-design.md +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/specs/2026-05-22-stay-mounted-batch-session-design.md +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/docs/superpowers/verifications/2026-05-11-phase-4-stage-g.md +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/examples/README.md +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/examples/batch_from_config.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/examples/multi_prompt_t2i.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/examples/sample_config.json +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/examples/sample_prompts.txt +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/examples/single_image_t2i.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/samples/README.md +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/samples/captured/01_upload_image.json +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/samples/captured/02_batchAsyncGenerateVideoText.json +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/samples/captured/03_batchCheckAsyncVideoGenerationStatus.json +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/samples/captured/04_archive_workflow.json +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/samples/captured/05_createProject.json +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/samples/captured/06_batchGenerateImages.json +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/samples/captured/07_batchGenerateImages_seeded.json +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/samples/captured/08_batchAsyncGenerateVideoStartAndEndImage.json +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/samples/captured/09_batchAsyncGenerateVideoReferenceImages.json +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/samples/captured/10_batchCheckAsyncVideoGenerationStatus_successful.json +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/samples/captured/11_batchCheckAsyncVideoGenerationStatus_failed.json +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/scripts/ci/check_doc_links.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/scripts/ci/check_repo_hygiene.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/scripts/debug_editor.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/scripts/debug_gen_settings.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/scripts/debug_settings.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/scripts/dev/active_plan.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/scripts/dev/monitor_pr_38.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/scripts/diag_capture_flow_traffic.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/scripts/diag_recaptcha_mint.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/scripts/record_demo.ps1 +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/scripts/smoke_image.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/scripts/smoke_real_chrome_image.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/scripts/smoke_video_editor.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/scripts/smoke_worker_style.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/scripts/verify_chrome_auth_viability.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/skills/README.md +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/skills/gflow-cli/SKILL.md +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/sonar-project.properties +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/src/gflow_cli/__main__.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/src/gflow_cli/_cli_helpers.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/src/gflow_cli/api/__init__.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/src/gflow_cli/api/_retry.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/src/gflow_cli/api/recaptcha.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/src/gflow_cli/api/routes.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/src/gflow_cli/api/transports/__init__.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/src/gflow_cli/api/transports/_fingerprint.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/src/gflow_cli/api/transports/experimental/__init__.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/src/gflow_cli/api/transports/experimental/bearer.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/src/gflow_cli/api/transports/experimental/evaluate_fetch.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/src/gflow_cli/api/transports/experimental/sapisidhash.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/src/gflow_cli/auth/__init__.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/src/gflow_cli/auth/base.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/src/gflow_cli/auth/factory.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/src/gflow_cli/auth/strategies.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/src/gflow_cli/auth/verification.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/src/gflow_cli/cli_run.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/src/gflow_cli/manifest.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/src/gflow_cli/observability.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/src/gflow_cli/profile_store.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tasks/lessons.md +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/test_assets/sample_batch.json +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/test_assets/sample_batch.tsv +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/test_assets/sample_batch_invalid.tsv +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/__init__.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/api/__init__.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/api/test_client_image.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/api/test_dto.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/api/test_image.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/api/test_image_dto.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/api/test_recaptcha.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/api/test_retry.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/api/test_routes.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/api/transports/__init__.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/api/transports/test_base.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/api/transports/test_bearer.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/api/transports/test_evaluate_fetch.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/api/transports/test_factory.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/api/transports/test_fingerprint.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/api/transports/test_sapisidhash.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/api/transports/test_ui_automation_batch.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/api/transports/test_ui_automation_image_mode.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/auth/strategies/test_factory.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/auth/strategies/test_strategies.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/auth/test_verification.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/cli/__init__.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/cli/test_cli_image_seed_removed.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/cli/test_cli_run.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/cli/test_error_handling.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/cli/test_helpers.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/cli/test_t2i_multi_prompt.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/conftest.py +0 -0
- {gflow_cli-0.8.1/tests/e2e → gflow_cli-0.9.0/tests/data}/__init__.py +0 -0
- {gflow_cli-0.8.1/tests/features → gflow_cli-0.9.0/tests/e2e}/__init__.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/e2e/conftest.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/e2e/test_auth_verification_e2e.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/e2e/test_image_batch_e2e.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/e2e/test_video_t2v_e2e.py +0 -0
- {gflow_cli-0.8.1/tests/image_batch → gflow_cli-0.9.0/tests/features}/__init__.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/features/auth.feature +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/features/auth_login.feature +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/features/conftest.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/features/image.feature +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/features/test_auth_login_steps.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/features/test_auth_steps.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/features/test_step_collision_guard.py +0 -0
- {gflow_cli-0.8.1/tests/smoke → gflow_cli-0.9.0/tests/fixtures}/__init__.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/smoke/test_real_flow.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/test_auth.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/test_browser_manager.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/test_config.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/test_manifest.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/test_observability.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/test_paths.py +0 -0
- {gflow_cli-0.8.1 → gflow_cli-0.9.0}/tests/test_profile_store.py +0 -0
- {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–
|
|
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.
|
|
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
|
-
|
|
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.
|
|
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
|
[](https://pypi.org/project/gflow-cli/)
|
|
60
60
|
[](https://github.com/ffroliva/gflow-cli/actions/workflows/ci.yml)
|
|
61
|
+
[](https://github.com/ffroliva/gflow-cli/actions/workflows/release.yml)
|
|
61
62
|
[](https://pypi.org/project/gflow-cli/)
|
|
62
63
|
[](LICENSE)
|
|
63
64
|
[](docs/PROJECT_STATUS.md)
|
|
65
|
+
[](https://github.com/astral-sh/ruff)
|
|
66
|
+
[](https://github.com/microsoft/pyright)
|
|
67
|
+
[](CONTRIBUTING.md)
|
|
68
|
+
[](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
|
|
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`)
|
|
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.
|
|
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
|
+
[](https://github.com/ffroliva/gflow-cli/stargazers)
|
|
178
|
+
[](https://github.com/ffroliva/gflow-cli/network/members)
|
|
179
|
+
[](https://github.com/ffroliva/gflow-cli/watchers)
|
|
180
|
+
[](https://github.com/ffroliva/gflow-cli/issues)
|
|
181
|
+
[](https://github.com/ffroliva/gflow-cli/pulls)
|
|
182
|
+
[](https://github.com/ffroliva/gflow-cli/commits/main)
|
|
183
|
+
[](https://github.com/ffroliva/gflow-cli)
|
|
184
|
+
[](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-
|
|
5
|
+
> **Last revised:** 2026-05-24 (develop — post-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.
|
|
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 —
|
|
595
|
+
### Phase 6 — Local SQLite data layer — IMPLEMENTED (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
|
-
|
|
606
|
+
**Backlog follow-ons (not in this PR):**
|
|
584
607
|
|
|
585
|
-
-
|
|
586
|
-
-
|
|
587
|
-
-
|
|
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
|
[](https://pypi.org/project/gflow-cli/)
|
|
6
6
|
[](https://github.com/ffroliva/gflow-cli/actions/workflows/ci.yml)
|
|
7
|
+
[](https://github.com/ffroliva/gflow-cli/actions/workflows/release.yml)
|
|
7
8
|
[](https://pypi.org/project/gflow-cli/)
|
|
8
9
|
[](LICENSE)
|
|
9
10
|
[](docs/PROJECT_STATUS.md)
|
|
11
|
+
[](https://github.com/astral-sh/ruff)
|
|
12
|
+
[](https://github.com/microsoft/pyright)
|
|
13
|
+
[](CONTRIBUTING.md)
|
|
14
|
+
[](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
|
|
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`)
|
|
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.
|
|
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
|
+
[](https://github.com/ffroliva/gflow-cli/stargazers)
|
|
124
|
+
[](https://github.com/ffroliva/gflow-cli/network/members)
|
|
125
|
+
[](https://github.com/ffroliva/gflow-cli/watchers)
|
|
126
|
+
[](https://github.com/ffroliva/gflow-cli/issues)
|
|
127
|
+
[](https://github.com/ffroliva/gflow-cli/pulls)
|
|
128
|
+
[](https://github.com/ffroliva/gflow-cli/commits/main)
|
|
129
|
+
[](https://github.com/ffroliva/gflow-cli)
|
|
130
|
+
[](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:
|