gflow-cli 0.9.0__tar.gz → 0.10.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.10.0/.claude/commands/gflow/branch-review.md +13 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/.claude/commands/gflow/check.md +5 -1
- gflow_cli-0.10.0/.claude/commands/gflow/pr-council-review.md +11 -0
- gflow_cli-0.10.0/.claude/commands/gflow/predict.md +19 -0
- gflow_cli-0.10.0/.claude/commands/gflow/scenario.md +23 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/.env.template +28 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/.github/PULL_REQUEST_TEMPLATE.md +2 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/.github/workflows/ci.yml +11 -10
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/.github/workflows/release.yml +2 -1
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/.gitignore +5 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/AGENTS.md +4 -2
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/CHANGELOG.md +267 -1
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/CONTRIBUTING.md +27 -3
- gflow_cli-0.10.0/GEMINI.md +27 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/KNOWN_ISSUES.md +110 -26
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/PKG-INFO +13 -3
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/PLAN.md +37 -20
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/README.md +6 -2
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/RELEASE.md +17 -1
- gflow_cli-0.10.0/conftest.py +48 -0
- gflow_cli-0.10.0/docker-compose.yml +47 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/docs/AGENT_GUIDE.md +15 -1
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/docs/ARCHITECTURE.md +12 -8
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/docs/AUTHENTICATION.md +121 -5
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/docs/CONFIGURATION.md +73 -4
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/docs/DATA_LAYER.md +79 -13
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/docs/DEVELOPMENT.md +13 -1
- gflow_cli-0.10.0/docs/E2E_TESTING.md +272 -0
- gflow_cli-0.10.0/docs/EXTERNAL_STORAGE.md +140 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/docs/GITHUB.md +38 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/docs/INDEX.md +9 -1
- gflow_cli-0.10.0/docs/LIVE_VERIFICATION_v0.10.0.md +95 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/docs/LIVE_VERIFICATION_v0.9.0.md +2 -0
- gflow_cli-0.10.0/docs/LIVE_VERIFICATION_v0.9.1.md +98 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/docs/PROJECT_STATUS.md +11 -5
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/docs/SECURITY.md +29 -2
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/docs/USAGE.md +108 -7
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/docs/USER_GUIDE.md +70 -1
- gflow_cli-0.10.0/docs/superpowers/specs/2026-05-27-public-event-surface-design.md +397 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/examples/README.md +3 -1
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/examples/sample_config.json +1 -1
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/examples/single_image_t2i.py +6 -4
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/llms.txt +1 -0
- gflow_cli-0.10.0/pyproject.toml +127 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/scripts/ci/check_doc_links.py +13 -0
- gflow_cli-0.10.0/scripts/dev/capture_i2v_frame_slots_dom.py +198 -0
- gflow_cli-0.10.0/scripts/dev/capture_locale_invariants.py +235 -0
- gflow_cli-0.10.0/scripts/dev/cdp_drive_and_probe.py +119 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/scripts/record_demo.ps1 +5 -2
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/skills/README.md +8 -0
- gflow_cli-0.10.0/skills/pr-council-review/SKILL.md +350 -0
- gflow_cli-0.10.0/skills/predict/SKILL.md +208 -0
- gflow_cli-0.10.0/skills/scenario/SKILL.md +200 -0
- gflow_cli-0.10.0/sonar-project.properties +54 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/src/gflow_cli/__init__.py +1 -1
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/src/gflow_cli/_cli_helpers.py +32 -6
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/src/gflow_cli/api/_retry.py +7 -4
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/src/gflow_cli/api/client.py +92 -65
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/src/gflow_cli/api/dto.py +13 -7
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/src/gflow_cli/api/image.py +62 -10
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/src/gflow_cli/api/recaptcha.py +12 -3
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/src/gflow_cli/api/routes.py +2 -1
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/src/gflow_cli/api/transports/__init__.py +2 -1
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/src/gflow_cli/api/transports/_common.py +17 -9
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/src/gflow_cli/api/transports/_fingerprint.py +5 -5
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/src/gflow_cli/api/transports/base.py +5 -4
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/src/gflow_cli/api/transports/experimental/bearer.py +32 -16
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/src/gflow_cli/api/transports/experimental/evaluate_fetch.py +26 -12
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/src/gflow_cli/api/transports/experimental/sapisidhash.py +39 -15
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/src/gflow_cli/api/transports/ui_automation.py +309 -118
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/src/gflow_cli/api/transports/ui_automation_video.py +216 -80
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/src/gflow_cli/api/video.py +155 -59
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/src/gflow_cli/auth/__init__.py +5 -2
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/src/gflow_cli/auth/base.py +4 -2
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/src/gflow_cli/auth/factory.py +9 -3
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/src/gflow_cli/auth/internal_chromium.py +31 -10
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/src/gflow_cli/auth/real_chrome.py +19 -7
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/src/gflow_cli/auth/verification.py +18 -9
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/src/gflow_cli/browser_manager.py +23 -10
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/src/gflow_cli/cli.py +90 -8
- gflow_cli-0.10.0/src/gflow_cli/cli_data.py +452 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/src/gflow_cli/cli_image.py +139 -35
- gflow_cli-0.10.0/src/gflow_cli/cli_models.py +121 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/src/gflow_cli/cli_run.py +34 -16
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/src/gflow_cli/cli_video.py +100 -10
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/src/gflow_cli/config.py +34 -2
- gflow_cli-0.10.0/src/gflow_cli/data/migrations/0002_add_cloud_storage.sql +20 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/src/gflow_cli/data/models.py +7 -3
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/src/gflow_cli/data/queries.py +137 -37
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/src/gflow_cli/data/recorder.py +82 -31
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/src/gflow_cli/data/redaction.py +2 -2
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/src/gflow_cli/data/repository.py +68 -17
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/src/gflow_cli/data/store.py +18 -9
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/src/gflow_cli/errors.py +16 -16
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/src/gflow_cli/image_batch.py +125 -50
- gflow_cli-0.10.0/src/gflow_cli/json_output.py +176 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/src/gflow_cli/manifest.py +2 -1
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/src/gflow_cli/observability.py +13 -5
- gflow_cli-0.10.0/src/gflow_cli/paths.py +212 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/src/gflow_cli/profile_store.py +68 -6
- gflow_cli-0.10.0/src/gflow_cli/storage.py +145 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/tests/api/test_client.py +16 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/tests/api/test_client_image.py +61 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/tests/api/test_image.py +44 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/tests/api/test_video.py +41 -5
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/tests/api/transports/test_bearer.py +6 -2
- gflow_cli-0.10.0/tests/api/transports/test_transport_timeout.py +98 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/tests/api/transports/test_ui_automation.py +148 -4
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/tests/api/transports/test_ui_automation_video.py +144 -1
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/tests/auth/strategies/test_strategies.py +6 -0
- gflow_cli-0.10.0/tests/cli/test_cli_auth_list.py +143 -0
- gflow_cli-0.10.0/tests/cli/test_cli_data.py +277 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/tests/cli/test_cli_image.py +180 -3
- gflow_cli-0.10.0/tests/cli/test_cli_models.py +92 -0
- gflow_cli-0.10.0/tests/cli/test_cli_video.py +475 -0
- gflow_cli-0.10.0/tests/conftest.py +80 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/tests/data/test_recorder.py +59 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/tests/data/test_settings_and_errors.py +2 -1
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/tests/data/test_store_migrations.py +1 -1
- gflow_cli-0.10.0/tests/e2e/conftest.py +123 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/tests/e2e/test_auth_verification_e2e.py +1 -1
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/tests/e2e/test_data_layer_e2e.py +10 -31
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/tests/e2e/test_image_batch_e2e.py +10 -19
- gflow_cli-0.10.0/tests/e2e/test_image_i2i_ref_cap_e2e.py +117 -0
- gflow_cli-0.10.0/tests/e2e/test_json_output_e2e.py +213 -0
- gflow_cli-0.10.0/tests/e2e/test_locale_selectors_e2e.py +88 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/tests/e2e/test_transports_e2e.py +157 -127
- gflow_cli-0.10.0/tests/e2e/test_video_r2v_ref_cap_e2e.py +161 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/tests/e2e/test_video_t2v_e2e.py +26 -44
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/tests/features/test_image_steps.py +1 -0
- gflow_cli-0.10.0/tests/integration/conftest.py +163 -0
- gflow_cli-0.10.0/tests/integration/constants.py +13 -0
- gflow_cli-0.10.0/tests/integration/test_storage_gcs.py +57 -0
- gflow_cli-0.10.0/tests/integration/test_storage_s3.py +87 -0
- gflow_cli-0.10.0/tests/scripts/test_capture_locale_invariants.py +77 -0
- gflow_cli-0.10.0/tests/smoke/__init__.py +0 -0
- gflow_cli-0.10.0/tests/smoke/test_profile_account_smoke.py +181 -0
- gflow_cli-0.10.0/tests/smoke/test_real_flow.py +118 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/tests/test_browser_manager.py +8 -2
- gflow_cli-0.10.0/tests/test_cli_data.py +414 -0
- gflow_cli-0.10.0/tests/test_conftest_isolation.py +40 -0
- gflow_cli-0.10.0/tests/test_data_queries.py +613 -0
- gflow_cli-0.10.0/tests/test_documentation_gate.py +34 -0
- gflow_cli-0.10.0/tests/test_json_output.py +148 -0
- gflow_cli-0.10.0/tests/test_marker_registry.py +173 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/tests/test_observability.py +23 -4
- gflow_cli-0.10.0/tests/test_paths.py +211 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/tests/test_profile_store.py +50 -0
- gflow_cli-0.10.0/uv.lock +2477 -0
- gflow_cli-0.9.0/docs/superpowers/notes/v0.9.0-schema-reconciliation.md +0 -108
- gflow_cli-0.9.0/docs/superpowers/plans/2026-05-24-v0.9.0-release-implementation.md +0 -2123
- gflow_cli-0.9.0/docs/superpowers/specs/2026-05-24-v0.9.0-release-design.md +0 -204
- gflow_cli-0.9.0/pyproject.toml +0 -86
- gflow_cli-0.9.0/scripts/dev/capture_locale_invariants.py +0 -87
- gflow_cli-0.9.0/sonar-project.properties +0 -35
- gflow_cli-0.9.0/src/gflow_cli/cli_data.py +0 -299
- gflow_cli-0.9.0/src/gflow_cli/paths.py +0 -102
- gflow_cli-0.9.0/tests/cli/test_cli_data.py +0 -81
- gflow_cli-0.9.0/tests/cli/test_cli_video.py +0 -208
- gflow_cli-0.9.0/tests/conftest.py +0 -38
- gflow_cli-0.9.0/tests/e2e/conftest.py +0 -67
- gflow_cli-0.9.0/tests/smoke/test_real_flow.py +0 -88
- gflow_cli-0.9.0/tests/test_cli_data.py +0 -147
- gflow_cli-0.9.0/tests/test_data_queries.py +0 -151
- gflow_cli-0.9.0/tests/test_paths.py +0 -51
- gflow_cli-0.9.0/uv.lock +0 -1169
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/.claude/README.md +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/.claude/commands/gflow/changelog.md +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/.claude/commands/gflow/doc-review.md +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/.claude/commands/gflow/known-issues.md +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/.claude/commands/gflow/plan.md +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/.claude/commands/gflow/release.md +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/.continue-here.md +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/.gitattributes +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/.github/CODEOWNERS +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/.github/copilot-instructions.md +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/.github/dependabot.yml +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/.github/workflows/external-pr-triage.yml +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/.gitleaks.toml +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/.planning/todos/pending/2026-05-11-add-project-logo-and-docs-site-promotion-plan.md +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/.planning/todos/pending/pr-38-review.md +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/.pre-commit-config.yaml +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/.secrets.baseline +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/CLAUDE.md +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/CONFIGURATION.md +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/DISCLAIMER.md +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/LICENSE +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/ROADMAP.md +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/docs/DEBUGGING.md +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/docs/LIVE_VERIFICATION_data_layer.md +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/docs/LIVE_VERIFICATION_image_batch.md +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/docs/LIVE_VERIFICATION_v0.7.0.md +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/docs/LIVE_VERIFICATION_v0.8.1.md +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/docs/LIVE_VERIFICATION_video_download.md +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/docs/assets/example-run.gif +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/docs/superpowers/2026-05-17-issue-15-handover.md +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/docs/superpowers/plans/2026-05-09-image-mvp-orchestration.md +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/docs/superpowers/plans/2026-05-09-image-mvp.md +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/docs/superpowers/plans/2026-05-09-video-mvp-orchestration.md +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/docs/superpowers/plans/2026-05-09-video-mvp.md +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/docs/superpowers/plans/2026-05-10-phase-4-hardening-orchestration.md +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/docs/superpowers/plans/2026-05-10-phase-4-hardening.md +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/docs/superpowers/plans/2026-05-14-shell-multi-prompt/2026-05-14-shell-multi-prompt-orchestration.md +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/docs/superpowers/plans/2026-05-14-shell-multi-prompt/COUNCIL_FINAL_ARCH.md +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/docs/superpowers/plans/2026-05-14-shell-multi-prompt/COUNCIL_FINAL_SEC_UX.md +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/docs/superpowers/plans/2026-05-14-shell-multi-prompt/COUNCIL_REVIEW_CODE.md +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/docs/superpowers/plans/2026-05-14-shell-multi-prompt/COUNCIL_REVIEW_GEMINI.md +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/docs/superpowers/plans/2026-05-14-shell-multi-prompt/COUNCIL_REVIEW_SECURITY.md +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/docs/superpowers/plans/2026-05-14-shell-multi-prompt/IMPLEMENTATION_REVIEW_PYTHON.md +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/docs/superpowers/plans/2026-05-14-shell-multi-prompt/IMPLEMENTATION_REVIEW_SECURITY.md +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/docs/superpowers/plans/2026-05-14-shell-multi-prompt/PLAN.md +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/docs/superpowers/plans/2026-05-14-shell-multi-prompt/PLAN_REVIEW_CODE.md +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/docs/superpowers/plans/2026-05-14-shell-multi-prompt/PLAN_REVIEW_FOLLOWUP.md +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/docs/superpowers/plans/2026-05-14-shell-multi-prompt/PLAN_REVIEW_PLANNER.md +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/docs/superpowers/plans/2026-05-14-shell-multi-prompt/PLAN_REVIEW_SECURITY.md +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/docs/superpowers/plans/2026-05-14-shell-multi-prompt/PLAN_REVIEW_SECURITY_FOLLOWUP.md +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/docs/superpowers/plans/2026-05-15-auth-login-real-chrome/COUNCIL_FINAL_SEC_UX_VERIFIED.md +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/docs/superpowers/plans/2026-05-15-auth-login-real-chrome/COUNCIL_REVIEW_PLAN_SECURITY.md +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/docs/superpowers/plans/2026-05-15-auth-login-real-chrome/COUNCIL_REVIEW_SPEC_SECURITY.md +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/docs/superpowers/plans/2026-05-15-auth-login-real-chrome/PLAN.md +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/docs/superpowers/plans/2026-05-15-auth-login-real-chrome/orchestration.md +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/docs/superpowers/plans/2026-05-17-e2e-test-coverage.md +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/docs/superpowers/plans/2026-05-17-issue-15-auth-verification-fix.md +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/docs/superpowers/plans/2026-05-17-issue-15-i2v-bearer-auth.md +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/docs/superpowers/plans/2026-05-17-issue-15-orchestration.md +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/docs/superpowers/plans/2026-05-18-video-phase0-submit-spike.md +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/docs/superpowers/plans/2026-05-19-video-phase-a-execution-state.md +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/docs/superpowers/plans/2026-05-19-video-phase-a-orchestration.md +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/docs/superpowers/plans/2026-05-19-video-phase-a-t2v.md +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/docs/superpowers/plans/2026-05-20-video-download-t2v-cli.md +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/docs/superpowers/plans/2026-05-21-multi-image-prompt-orchestration.md +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/docs/superpowers/plans/2026-05-21-multi-image-prompt.md +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/docs/superpowers/plans/2026-05-22-pr-38-review.md +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/docs/superpowers/plans/2026-05-22-stay-mounted-batch-session-plan.md +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/docs/superpowers/plans/2026-05-23-locale-agnostic-selectors.md +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/docs/superpowers/plans/2026-05-24-data-layer.md +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/docs/superpowers/specs/2026-05-10-phase-4-hardening-design.md +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/docs/superpowers/specs/2026-05-14-shell-multi-prompt-design.md +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/docs/superpowers/specs/2026-05-15-auth-login-real-chrome-design.md +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/docs/superpowers/specs/2026-05-17-e2e-test-coverage-design.md +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/docs/superpowers/specs/2026-05-17-i2v-uploadimage-401-bearer-auth-design.md +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/docs/superpowers/specs/2026-05-17-issue-15-auth-verification-fix-design.md +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/docs/superpowers/specs/2026-05-17-issue-15-root-cause-findings.md +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/docs/superpowers/specs/2026-05-18-ui-automation-video-generation-design.md +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/docs/superpowers/specs/2026-05-21-multi-image-prompt-design.md +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/docs/superpowers/specs/2026-05-22-pr-38-review-design.md +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/docs/superpowers/specs/2026-05-22-stay-mounted-batch-session-design.md +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/docs/superpowers/specs/2026-05-23-locale-agnostic-selectors.md +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/docs/superpowers/specs/2026-05-23-readme-v0.8.1-refresh-design.md +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/docs/superpowers/specs/2026-05-24-data-layer-design.md +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/docs/superpowers/verifications/2026-05-11-phase-4-stage-g.md +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/examples/batch_from_config.py +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/examples/multi_prompt_t2i.py +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/examples/sample_prompts.txt +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/samples/README.md +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/samples/captured/01_upload_image.json +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/samples/captured/02_batchAsyncGenerateVideoText.json +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/samples/captured/03_batchCheckAsyncVideoGenerationStatus.json +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/samples/captured/04_archive_workflow.json +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/samples/captured/05_createProject.json +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/samples/captured/06_batchGenerateImages.json +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/samples/captured/07_batchGenerateImages_seeded.json +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/samples/captured/08_batchAsyncGenerateVideoStartAndEndImage.json +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/samples/captured/09_batchAsyncGenerateVideoReferenceImages.json +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/samples/captured/10_batchCheckAsyncVideoGenerationStatus_successful.json +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/samples/captured/11_batchCheckAsyncVideoGenerationStatus_failed.json +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/scripts/ci/check_repo_hygiene.py +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/scripts/debug_editor.py +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/scripts/debug_gen_settings.py +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/scripts/debug_settings.py +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/scripts/dev/active_plan.py +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/scripts/dev/capture_image_add_media_dom.py +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/scripts/dev/monitor_pr_38.py +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/scripts/diag_capture_flow_traffic.py +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/scripts/diag_recaptcha_mint.py +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/scripts/smoke_image.py +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/scripts/smoke_real_chrome_image.py +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/scripts/smoke_video_editor.py +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/scripts/smoke_worker_style.py +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/scripts/verify_chrome_auth_viability.py +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/skills/gflow-cli/SKILL.md +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/src/gflow_cli/__main__.py +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/src/gflow_cli/api/__init__.py +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/src/gflow_cli/api/transports/experimental/__init__.py +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/src/gflow_cli/auth/strategies.py +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/src/gflow_cli/data/__init__.py +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/src/gflow_cli/data/migrations/0001_initial.sql +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/src/gflow_cli/data/migrations/__init__.py +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/src/gflow_cli/exceptions.py +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/tasks/lessons.md +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/test_assets/sample_batch.json +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/test_assets/sample_batch.tsv +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/test_assets/sample_batch_invalid.tsv +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/tests/__init__.py +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/tests/api/__init__.py +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/tests/api/test_concurrency.py +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/tests/api/test_dto.py +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/tests/api/test_image_dto.py +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/tests/api/test_recaptcha.py +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/tests/api/test_retry.py +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/tests/api/test_routes.py +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/tests/api/transports/__init__.py +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/tests/api/transports/test_base.py +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/tests/api/transports/test_common.py +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/tests/api/transports/test_evaluate_fetch.py +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/tests/api/transports/test_factory.py +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/tests/api/transports/test_fingerprint.py +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/tests/api/transports/test_sapisidhash.py +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/tests/api/transports/test_ui_automation_batch.py +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/tests/api/transports/test_ui_automation_image_mode.py +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/tests/auth/strategies/test_factory.py +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/tests/auth/test_verification.py +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/tests/cli/__init__.py +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/tests/cli/test_cli_image_seed_removed.py +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/tests/cli/test_cli_run.py +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/tests/cli/test_error_handling.py +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/tests/cli/test_helpers.py +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/tests/cli/test_t2i_multi_prompt.py +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/tests/data/__init__.py +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/tests/data/test_packaging.py +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/tests/data/test_redaction.py +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/tests/data/test_repository.py +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/tests/e2e/__init__.py +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/tests/features/__init__.py +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/tests/features/auth.feature +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/tests/features/auth_login.feature +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/tests/features/conftest.py +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/tests/features/image.feature +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/tests/features/test_auth_login_steps.py +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/tests/features/test_auth_steps.py +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/tests/features/test_step_collision_guard.py +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/tests/fixtures/__init__.py +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/tests/fixtures/seeded_catalog.py +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/tests/image_batch/__init__.py +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/tests/image_batch/test_image_manifest.py +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/tests/image_batch/test_observability_events.py +0 -0
- {gflow_cli-0.9.0/tests/smoke → gflow_cli-0.10.0/tests/integration}/__init__.py +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/tests/test_auth.py +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/tests/test_config.py +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/tests/test_errors.py +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/tests/test_manifest.py +0 -0
- {gflow_cli-0.9.0 → gflow_cli-0.10.0}/tests/test_smoke.py +0 -0
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Multi-dimensional LLM council review on the current local feature branch — pre-PR review. Same dimensions as `/gflow:pr-council-review` but reads `git diff <base>..HEAD` instead of a PR; never posts to GitHub. Wrapper around skills/pr-council-review/SKILL.md § 8 (branch mode).
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# `/gflow:branch-review [--base <ref>]`
|
|
6
|
+
|
|
7
|
+
**Read `skills/pr-council-review/SKILL.md` and follow its protocol now in BRANCH MODE (§ 8)**, passing `$ARGUMENTS` (optional `--base <ref>`; default `develop`).
|
|
8
|
+
|
|
9
|
+
> Do **not** call `Skill(skill="pr-council-review")` — the repo's `skills/*/SKILL.md` files are plain Markdown, not registered as Skill-tool-invocable (only `.claude/commands/gflow/*` are). Invoking it errors with `Unknown skill: pr-council-review`. Read the file directly instead.
|
|
10
|
+
|
|
11
|
+
The canonical body is `skills/pr-council-review/SKILL.md`. § 8 documents branch-mode-specific behavior: pre-flight, the PR→branch translation table, `release/*` downgrade, SHA drift, and local-only output. All other phases (gather context, detect dimensions, dispatch, synthesize, report) are identical to PR mode.
|
|
12
|
+
|
|
13
|
+
Sibling: `/gflow:pr-council-review <N>` runs the same council against an open PR.
|
|
@@ -32,7 +32,7 @@ uv run pyright src
|
|
|
32
32
|
**4. Tests + coverage** (report only)
|
|
33
33
|
|
|
34
34
|
```bash
|
|
35
|
-
uv run pytest -q --cov=gflow_cli --cov-fail-under=80
|
|
35
|
+
uv run python -m pytest -q --cov=gflow_cli --cov-fail-under=80
|
|
36
36
|
```
|
|
37
37
|
|
|
38
38
|
## Output
|
|
@@ -46,3 +46,7 @@ uv run pytest -q --cov=gflow_cli --cov-fail-under=80
|
|
|
46
46
|
|
|
47
47
|
Ruff fix and format may rewrite multiple files. Always `git diff` before staging.
|
|
48
48
|
Pyright errors and test failures require manual intervention — do not attempt silent workarounds.
|
|
49
|
+
If the coverage run crashes the current MCP/sandbox session with `Connection closed`, re-run the
|
|
50
|
+
same marker-filtered suite in smaller chunks without coverage and rely on CI for the coverage XML.
|
|
51
|
+
Project pytest defaults already exclude `e2e` and `live`; those markers are explicit,
|
|
52
|
+
credit-spending gates and must be requested with a separate `-m e2e` / `-m live` command.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Multi-dimensional LLM council review of an open PR. Five baseline dimensions (correctness, quality, security, tests, memory-hygiene) plus adaptive per-surface dimensions. Sub-agents invoke specialized skills (security-review, code-review, verify). With no argument, lists open PRs ranked by priority. Wrapper around skills/pr-council-review/SKILL.md (canonical body).
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# `/gflow:pr-council-review [PR#]`
|
|
6
|
+
|
|
7
|
+
**Read `skills/pr-council-review/SKILL.md` and follow its protocol now**, treating `$ARGUMENTS` as the PR number (or empty for prioritize-mode). That file is the canonical body: preflight, dimension detection, parallel dispatch, synthesis, report.
|
|
8
|
+
|
|
9
|
+
> Do **not** call `Skill(skill="pr-council-review")` — the repo's `skills/*/SKILL.md` files are plain Markdown, not registered as Skill-tool-invocable (only `.claude/commands/gflow/*` are). Invoking it errors with `Unknown skill: pr-council-review`. Read the file directly instead.
|
|
10
|
+
|
|
11
|
+
Sibling: `/review` is the single-agent Claude-Code built-in (fast, one-pass). Use it for spot-checks; use this command for pre-merge multi-dim audits.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: >
|
|
3
|
+
Pre-implementation 5-persona adversarial analysis for high-stakes gflow-cli proposals.
|
|
4
|
+
Produces a GO / CAUTION / STOP verdict before any code is written.
|
|
5
|
+
Invoke before new transports, auth changes, selector redesigns, schema migrations,
|
|
6
|
+
or any PLAN.md backlog item gated on an investigation step.
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# `/gflow:predict [proposal]`
|
|
10
|
+
|
|
11
|
+
**Read `skills/predict/SKILL.md` and follow its protocol now**, passing `$ARGUMENTS` as the proposal description.
|
|
12
|
+
|
|
13
|
+
> Do **not** call `Skill(skill="predict")` — the repo's `skills/*/SKILL.md` files are plain Markdown, not registered as Skill-tool-invocable (only `.claude/commands/gflow/*` are). Invoking it errors with `Unknown skill: predict`. Read the file directly instead.
|
|
14
|
+
|
|
15
|
+
The skill at `skills/predict/SKILL.md` runs five independent expert personas
|
|
16
|
+
(Architect · Security/reCAPTCHA · Performance/Playwright · CLI UX · Devil's Advocate),
|
|
17
|
+
resolves conflicts, and returns a GO / CAUTION / STOP verdict with a confidence score.
|
|
18
|
+
|
|
19
|
+
**Pair with `/gflow:scenario`** after a GO or CAUTION to enumerate edge cases before EXECUTE.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: >
|
|
3
|
+
Pre-implementation edge-case explorer for gflow-cli features.
|
|
4
|
+
Decomposes a proposed change across 12 gflow-cli-specific dimensions
|
|
5
|
+
(WAF/reCAPTCHA, selector drift, auth lifecycle, batch resume, data layer,
|
|
6
|
+
cross-platform paths, error propagation, observability) and produces a
|
|
7
|
+
severity-ranked scenario table and BDD skeleton.
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# `/gflow:scenario [feature description]`
|
|
11
|
+
|
|
12
|
+
**Read `skills/scenario/SKILL.md` and follow its protocol now**, passing `$ARGUMENTS` as the feature or change description.
|
|
13
|
+
|
|
14
|
+
> Do **not** call `Skill(skill="scenario")` — the repo's `skills/*/SKILL.md` files are plain Markdown, not registered as Skill-tool-invocable (only `.claude/commands/gflow/*` are). Invoking it errors with `Unknown skill: scenario`. Read the file directly instead.
|
|
15
|
+
|
|
16
|
+
The skill at `skills/scenario/SKILL.md` covers 12 dimensions tuned to gflow-cli's
|
|
17
|
+
known failure surfaces and outputs:
|
|
18
|
+
- A severity-ranked scenario table (Critical / High / Medium / Low)
|
|
19
|
+
- Must-cover acceptance criteria for the PLAN.md task
|
|
20
|
+
- Suggested BDD `Scenario:` blocks for `tests/features/`
|
|
21
|
+
- Cross-references to open KNOWN_ISSUES entries
|
|
22
|
+
|
|
23
|
+
**Typical order:** `/gflow:predict` → `/gflow:scenario` → PLAN.md task → `/gflow:check` → PR.
|
|
@@ -52,6 +52,34 @@
|
|
|
52
52
|
# Get one at https://aistudio.google.com/apikey
|
|
53
53
|
# GFLOW_CLI_GEMINI_API_KEY=
|
|
54
54
|
|
|
55
|
+
# -----------------------------------------------------------------------------
|
|
56
|
+
# Cloud storage
|
|
57
|
+
# -----------------------------------------------------------------------------
|
|
58
|
+
|
|
59
|
+
# Upload generated assets directly to a cloud bucket instead of saving local
|
|
60
|
+
# asset copies. Supported schemes:
|
|
61
|
+
# gs:// – Google Cloud Storage (requires: pip install 'gflow-cli[gcs]')
|
|
62
|
+
# s3:// – Amazon S3 or any S3-compatible store, e.g. MinIO
|
|
63
|
+
# (requires: pip install 'gflow-cli[s3]')
|
|
64
|
+
#
|
|
65
|
+
# Examples:
|
|
66
|
+
# GFLOW_CLI_STORAGE_URI=gs://my-gcs-bucket/gflow/
|
|
67
|
+
# GFLOW_CLI_STORAGE_URI=s3://my-s3-bucket/gflow/
|
|
68
|
+
# GFLOW_CLI_STORAGE_URI=s3://gflow-test/gflow/ # MinIO local dev
|
|
69
|
+
#
|
|
70
|
+
# For S3 / MinIO you also need the standard AWS SDK env vars:
|
|
71
|
+
# AWS_ACCESS_KEY_ID=minioadmin
|
|
72
|
+
# AWS_SECRET_ACCESS_KEY=minioadmin
|
|
73
|
+
# AWS_ENDPOINT_URL=http://localhost:9000 # omit for real AWS
|
|
74
|
+
# AWS_DEFAULT_REGION=us-east-1
|
|
75
|
+
#
|
|
76
|
+
# For GCS (local emulator):
|
|
77
|
+
# STORAGE_EMULATOR_HOST=http://localhost:4443
|
|
78
|
+
#
|
|
79
|
+
# When unset, assets are saved to GFLOW_CLI_OUTPUT_DIR (local disk). gflow-cli
|
|
80
|
+
# does not dual-write local + cloud copies; configure one storage target per run.
|
|
81
|
+
# GFLOW_CLI_STORAGE_URI=
|
|
82
|
+
|
|
55
83
|
# -----------------------------------------------------------------------------
|
|
56
84
|
# Runtime tuning
|
|
57
85
|
# -----------------------------------------------------------------------------
|
|
@@ -7,6 +7,8 @@
|
|
|
7
7
|
<!-- List the focused commands you ran, plus any checks you could not run. -->
|
|
8
8
|
|
|
9
9
|
- [ ] Focused tests added or updated for behavior changes
|
|
10
|
+
- [ ] Documentation updated or explicitly marked not applicable
|
|
11
|
+
- [ ] `uv run python scripts/ci/check_doc_links.py`
|
|
10
12
|
- [ ] `uv run ruff check src tests`
|
|
11
13
|
- [ ] `uv run pyright src`
|
|
12
14
|
- [ ] Relevant pytest command:
|
|
@@ -6,7 +6,9 @@ on:
|
|
|
6
6
|
pull_request:
|
|
7
7
|
|
|
8
8
|
env:
|
|
9
|
-
|
|
9
|
+
# Suppress Node.js deprecation warnings and align with user request to use Node 22/remove noise.
|
|
10
|
+
ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true
|
|
11
|
+
NODE_VERSION: '22'
|
|
10
12
|
|
|
11
13
|
jobs:
|
|
12
14
|
# ── Security gate: runs first, on every push/PR, never skippable ──────────
|
|
@@ -44,6 +46,9 @@ jobs:
|
|
|
44
46
|
- name: Repo hygiene (no artefacts, no hardcoded paths)
|
|
45
47
|
run: uv run python scripts/ci/check_repo_hygiene.py
|
|
46
48
|
|
|
49
|
+
- name: Documentation links
|
|
50
|
+
run: uv run python scripts/ci/check_doc_links.py
|
|
51
|
+
|
|
47
52
|
- name: Lint
|
|
48
53
|
run: uv run ruff check src tests
|
|
49
54
|
|
|
@@ -54,14 +59,10 @@ jobs:
|
|
|
54
59
|
run: uv run pyright src
|
|
55
60
|
|
|
56
61
|
- name: Test (smoke only) + coverage
|
|
57
|
-
# e2e tests
|
|
58
|
-
#
|
|
59
|
-
#
|
|
60
|
-
|
|
61
|
-
# `GFLOW_LIVE=1` tests that hit the real Flow API. Both are excluded
|
|
62
|
-
# from the default smoke run; `tests/smoke/test_real_flow.py` already
|
|
63
|
-
# self-skips via `pytest.mark.skipif(GFLOW_E2E != "1")`.
|
|
64
|
-
run: uv run python -m pytest -q -m "not e2e and not live" --cov=gflow_cli --cov-report=xml
|
|
62
|
+
# e2e/live tests require a logged-in Chromium profile and may spend
|
|
63
|
+
# Flow credits. pyproject.toml excludes both markers by default; CI
|
|
64
|
+
# intentionally relies on that default smoke set.
|
|
65
|
+
run: uv run python -m pytest -q --cov=gflow_cli --cov-report=xml
|
|
65
66
|
|
|
66
67
|
# Upload coverage XML so the sonar job can consume it
|
|
67
68
|
- name: Upload coverage report
|
|
@@ -98,7 +99,7 @@ jobs:
|
|
|
98
99
|
continue-on-error: true # graceful if coverage upload was skipped
|
|
99
100
|
|
|
100
101
|
- name: SonarCloud scan
|
|
101
|
-
uses: SonarSource/sonarcloud-github-action@
|
|
102
|
+
uses: SonarSource/sonarcloud-github-action@v5.0.0
|
|
102
103
|
env:
|
|
103
104
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # PR decoration
|
|
104
105
|
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} # set in repo → Settings → Secrets
|
|
@@ -18,6 +18,7 @@ env/
|
|
|
18
18
|
pytest-of-*/
|
|
19
19
|
.coverage
|
|
20
20
|
.coverage.*
|
|
21
|
+
coverage.xml
|
|
21
22
|
htmlcov/
|
|
22
23
|
.tox/
|
|
23
24
|
.mypy_cache/
|
|
@@ -70,6 +71,8 @@ samples/captured/flow_outgoing_*.jsonl
|
|
|
70
71
|
samples/captured/flow_outgoing_*.json
|
|
71
72
|
|
|
72
73
|
# Claude Code worktrees and lock files
|
|
74
|
+
.claude/settings.json
|
|
75
|
+
.claude/settings.local.json
|
|
73
76
|
.claude/worktrees/
|
|
74
77
|
.claude/scheduled_tasks.lock
|
|
75
78
|
|
|
@@ -78,3 +81,5 @@ samples/captured/flow_outgoing_*.json
|
|
|
78
81
|
|
|
79
82
|
worktrees/
|
|
80
83
|
|
|
84
|
+
# E2E test logs (live Flow runs — may contain account/profile names)
|
|
85
|
+
.planning/e2e-logs/
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
> Universal entry point for AI coding agents. Read this first; everything else routes from here.
|
|
4
4
|
|
|
5
|
-
Supported tools that auto-discover this file: Cursor, Codex, Aider,
|
|
5
|
+
Supported tools that auto-discover this file: Cursor, Codex, Aider, Jules, Devin, Windsurf, Zed, Warp, opencode, RooCode, Amp, Junie, Phoenix, GitHub Copilot, VS Code, Factory, Augment, Semgrep, Kilo Code, UiPath. Gemini CLI reads [GEMINI.md](GEMINI.md) and Claude Code reads [CLAUDE.md](CLAUDE.md), both of which cross-reference this file.
|
|
6
6
|
|
|
7
7
|
## Project at a glance
|
|
8
8
|
|
|
@@ -37,6 +37,7 @@ Run these gates in order before every commit:
|
|
|
37
37
|
```powershell
|
|
38
38
|
$env:PYTHONUTF8=1
|
|
39
39
|
uv run python scripts/ci/check_repo_hygiene.py
|
|
40
|
+
uv run python scripts/ci/check_doc_links.py
|
|
40
41
|
uv run ruff check src tests
|
|
41
42
|
uv run ruff format --check src tests
|
|
42
43
|
uv run pyright src
|
|
@@ -45,8 +46,9 @@ uv run python -m pytest -q --cov=gflow_cli
|
|
|
45
46
|
|
|
46
47
|
Or invoke the wrapper: `/gflow:check`.
|
|
47
48
|
|
|
48
|
-
- Use `pytest -m "not live and not e2e"` locally; full suite OOMs on small dev machines. Scope to changed dirs; trust CI for the full sweep.
|
|
49
|
+
- Use `pytest -m "not live and not e2e and not smoke"` locally; full suite OOMs on small dev machines. Scope to changed dirs; trust CI for the full sweep.
|
|
49
50
|
- TDD is non-negotiable. Coverage floor: 80% overall.
|
|
51
|
+
- Documentation is a first-class deliverable. Every behavior, workflow, config, or operator-facing change must update the relevant docs or state why no docs changed in the PR/checklist. `scripts/ci/check_doc_links.py` is a merge gate.
|
|
50
52
|
- Live tests (`@pytest.mark.live`) opt in via `GFLOW_LIVE=1`. E2E tests require `GFLOW_CLI_E2E_PROFILE`.
|
|
51
53
|
|
|
52
54
|
## Code style
|
|
@@ -7,6 +7,270 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.10.0] — 2026-05-29
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- **Image and video counts leaking across profiles in `gflow data list projects` (issue #113).**
|
|
15
|
+
Fixed an issue where project media counts were combined if two different profiles
|
|
16
|
+
happened to share the same `flow_project_id`. The counts in `_LIST_PROJECTS_SQL`
|
|
17
|
+
are now strictly scoped to the active `profile_name`.
|
|
18
|
+
|
|
19
|
+
- **List queries fan-out when multiple operations claim an asset (issue #111).**
|
|
20
|
+
Fixed a bug in `gflow data list images` and `gflow data list videos` where
|
|
21
|
+
assets would be duplicated or have non-deterministic prompts if multiple
|
|
22
|
+
operations (e.g., retries) claimed the same output asset. The SQL queries
|
|
23
|
+
now use a deterministic subquery grouping by `asset_id` to ensure exactly
|
|
24
|
+
one-to-one cardinality.
|
|
25
|
+
|
|
26
|
+
### Added
|
|
27
|
+
|
|
28
|
+
- **Google account identity persisted to every profile (`issue #92`).** Both
|
|
29
|
+
auth strategies (`real_chrome`, `internal_chromium`) now write a
|
|
30
|
+
`.gflow_account` file to the profile directory immediately after the session
|
|
31
|
+
is verified, durably associating the signed-in email with the profile on disk.
|
|
32
|
+
`ProfileMeta` gains a `google_account: str | None` field populated by
|
|
33
|
+
`profile_store.list_profiles()` from that file. `gflow auth list` (table and
|
|
34
|
+
`--json`) now includes a **Google account** column so every profile is
|
|
35
|
+
immediately identifiable — no more opaque `default` entries. The `--json`
|
|
36
|
+
output gains the `google_account` key for programmatic callers. Closes #92.
|
|
37
|
+
|
|
38
|
+
- **Auto-rename of the first-run `default` profile to email local-part.** When
|
|
39
|
+
`gflow auth login` creates the first profile and no `--profile` flag was given,
|
|
40
|
+
the profile is named `default` as a placeholder. After the session is verified
|
|
41
|
+
and the email is known, `auth login` automatically renames `profile_default` to
|
|
42
|
+
`profile_<email-local-part>` (e.g. `profile_ffroliva`) and updates
|
|
43
|
+
`config.toml`'s `default_profile` pointer atomically. The local-part is
|
|
44
|
+
sanitized to a filesystem-safe name (characters outside letters, digits, `-`,
|
|
45
|
+
and `_` become `-`), so `flavio.oliva@gmail.com` → `profile_flavio-oliva` and
|
|
46
|
+
`user+flow@gmail.com` → `profile_user-flow`. Existing `default`
|
|
47
|
+
profiles that were created before this change continue to work; they gain the
|
|
48
|
+
email column the next time `gflow auth login` is run against them. Closes #92.
|
|
49
|
+
|
|
50
|
+
- **`profile_store.rename_profile(old_name, new_name)`** — reusable primitive that
|
|
51
|
+
renames a profile directory and updates `config.toml` when the renamed profile
|
|
52
|
+
was the default. Raises `FileNotFoundError` / `FileExistsError` on invalid input.
|
|
53
|
+
|
|
54
|
+
- **Zero-credit smoke test for profile account persistence
|
|
55
|
+
(`tests/smoke/test_profile_account_smoke.py`).** Three smoke tests that verify
|
|
56
|
+
the full observable chain — account file present + readable, `list_profiles()`
|
|
57
|
+
surfaces `google_account`, `gflow auth list --json` includes the field — against
|
|
58
|
+
a real authenticated profile. No image or video generation; zero Flow credits.
|
|
59
|
+
Backfills the `.gflow_account` file for profiles created before the fix so the
|
|
60
|
+
tests work on existing sessions. Opt-in via
|
|
61
|
+
`GFLOW_CLI_E2E_PROFILE=<name> pytest -m smoke tests/smoke/test_profile_account_smoke.py`.
|
|
62
|
+
|
|
63
|
+
- **Aggregated asset view in `gflow data list images/videos`.** By default,
|
|
64
|
+
listing images or videos now returns one row per asset (Flow media ID),
|
|
65
|
+
collapsing multiple local copies into a single entry with a `COPIES` count
|
|
66
|
+
and the path of the latest copy. This prevents duplicate rows when
|
|
67
|
+
re-downloading the same media to different directories. The `copy_count`
|
|
68
|
+
is also exposed in JSONL output.
|
|
69
|
+
- **`--all-copies` flag on `gflow data list images/videos`.** Restores the
|
|
70
|
+
previous behavior of showing every local file as a separate row.
|
|
71
|
+
- **`gflow data prune` command.** New maintenance utility to remove stale
|
|
72
|
+
`local_files` database entries for local paths that no longer exist on
|
|
73
|
+
disk. Only targets local files (ignores cloud-stored assets). Supports
|
|
74
|
+
`--dry-run` to preview deletions and `--profile` to limit the scan.
|
|
75
|
+
- **External storage documentation for S3, MinIO, and Google Cloud Storage.**
|
|
76
|
+
Adds `docs/EXTERNAL_STORAGE.md`, cross-links it from the README, docs index,
|
|
77
|
+
configuration, data-layer, usage, security, and user-guide docs, and clarifies
|
|
78
|
+
that `GFLOW_CLI_STORAGE_URI` is a cloud-only output mode rather than
|
|
79
|
+
local-plus-cloud dual-write.
|
|
80
|
+
- **`--json` flag on `gflow video t2v`, `gflow video i2v`, and `gflow video r2v`.**
|
|
81
|
+
Emits the `VideoResult` (status / command / media_id / generation_status /
|
|
82
|
+
succeeded / local_path / failure_reasons / error_message) plus the request
|
|
83
|
+
echo (model / mode / aspect / duration / count / seed) as a single JSON
|
|
84
|
+
object on stdout. A failed generation still emits its JSON payload and
|
|
85
|
+
then exits 1. The data-layer recorder
|
|
86
|
+
(`record_started_video` / `record_completed_video`) fires regardless of
|
|
87
|
+
`--json` so audit history is independent of the output channel. E2e
|
|
88
|
+
coverage for `--json` shape across image / video / auth / models lives at
|
|
89
|
+
`tests/e2e/test_json_output_e2e.py`.
|
|
90
|
+
- **`--json` flag on `gflow image t2i` and `gflow image i2i`.** Emits the
|
|
91
|
+
complete `GeneratedImage` result (every field — `media_name`,
|
|
92
|
+
`workflow_id`, `seed`, `prompt`, `model_name_type`, `aspect_ratio`,
|
|
93
|
+
`dimensions`, `fife_url`, `is_signed_url`) plus the on-disk `local_path`
|
|
94
|
+
as a single JSON object on stdout. A worker keys `images[0].seed` for
|
|
95
|
+
refine-regen seed continuity. Single-prompt only (`--json` rejects
|
|
96
|
+
multi-prompt batch with a Click usage error); progress chatter is
|
|
97
|
+
suppressed so stdout is pure JSON. `ref_count` surfaces only on i2i.
|
|
98
|
+
- **`gflow models` catalog command.** New top-level command that enumerates
|
|
99
|
+
the image and video model catalog as a Rich table (default) or as a single
|
|
100
|
+
JSON object (`--json`). Per-model: `name`, CLI aliases (filtered to what
|
|
101
|
+
the generation command's `--model` Choice actually accepts), `ref_cap`,
|
|
102
|
+
`default` (image), `max_duration` (video). Built from the
|
|
103
|
+
`Model` / `VideoModel` enums + their alias maps so the catalog can never
|
|
104
|
+
drift from what the generation commands accept. A UI populating its model
|
|
105
|
+
picker from `gflow models --json` is guaranteed to pass any selected alias
|
|
106
|
+
back to `--model`.
|
|
107
|
+
- **`gflow_cli.json_output` module + `--json` error path on
|
|
108
|
+
`run_with_handlers`.** Pure builders for image/video result payloads and
|
|
109
|
+
RFC 9457 problem-details errors (plus a `retryable` flag worker schedulers
|
|
110
|
+
key their retry-vs-absorb decision off — WAF / rate-limit / network /
|
|
111
|
+
timeout). When `as_json=True`, errors emit a parseable JSON payload on
|
|
112
|
+
stdout with the same exit code as the Rich path; the observability event
|
|
113
|
+
still fires.
|
|
114
|
+
- **`--json` flag on `gflow auth list`.** Emits the profile inventory as a JSON
|
|
115
|
+
array (`name` / `is_default` / `cookies_present` / `profile_dir` /
|
|
116
|
+
`last_used_at`) on stdout so a programmatic caller (e.g. a worker discovering
|
|
117
|
+
authenticated profiles) can `json.loads(stdout)` instead of scraping the
|
|
118
|
+
Rich table.
|
|
119
|
+
- **Per-model r2v reference-image cap rebuilt as a data table.** Replaces the
|
|
120
|
+
prior pair of constants (`OMNI_REFERENCE_CAP=7`, `VEO_REFERENCE_CAP=3`) with
|
|
121
|
+
a `VideoModel -> int` mapping consulted by
|
|
122
|
+
`gflow_cli.api.video.reference_cap_for(model)`. New entries:
|
|
123
|
+
`veo_3_1_lite_lower_priority=3` (was implicitly covered by the veo branch),
|
|
124
|
+
and `veo_3_1_quality=0` — Veo 3.1 Quality does NOT support
|
|
125
|
+
Ingredients/References to Video at all per Google Flow's official support
|
|
126
|
+
page; passing it to r2v raises a clear `does not support R2V
|
|
127
|
+
(reference-to-video)` error rather than letting the request fail at the
|
|
128
|
+
wire. CLI guard added on `gflow video r2v` (`click.UsageError`, exit 2)
|
|
129
|
+
mirroring the i2i pattern so over-cap and quality+r2v fail before any
|
|
130
|
+
profile/network work. E2e tripwire at
|
|
131
|
+
`tests/e2e/test_video_r2v_ref_cap_e2e.py` asserts Flow actually consumes
|
|
132
|
+
all `cap` refs at the at-cap boundary.
|
|
133
|
+
- **Per-model i2i reference-image cap.** Flow silently keeps only the first N
|
|
134
|
+
reference images when an i2i request attaches more than the model accepts,
|
|
135
|
+
so a caller could believe every ref was used. `gflow_cli.api.image.reference_cap_for(model)`
|
|
136
|
+
exposes the live-observed per-model cap: NARWHAL (Nano Banana 2) and GEM_PIX_2
|
|
137
|
+
(Nano Pro) accept 10, IMAGEN_3_5 (Imagen 4) accepts 3. Enforced as a domain
|
|
138
|
+
invariant in `GenerateImageRequest.__post_init__` and at the CLI boundary in
|
|
139
|
+
`gflow image i2i` (clean `click.UsageError` / exit 2 before any
|
|
140
|
+
profile/network work). Mirrors the existing video r2v cap pattern. E2e
|
|
141
|
+
tripwire at `tests/e2e/test_image_i2i_ref_cap_e2e.py` asserts Flow actually
|
|
142
|
+
consumes all `cap` refs (one `reference_attached` event per ref) so a future
|
|
143
|
+
silent truncation on the Flow side fails the test.
|
|
144
|
+
- **Layered e2e test strategy with cost sub-markers.** The single `e2e` marker is
|
|
145
|
+
now augmented by cost sub-markers (`e2e_auth`, `e2e_image`, `e2e_video`,
|
|
146
|
+
`e2e_batch`, `e2e_data`, `smoke`) so callers can run only the tier they can
|
|
147
|
+
afford (zero-credit auth checks, single-credit image smoke, etc.). See
|
|
148
|
+
`docs/E2E_TESTING.md` for the full reference.
|
|
149
|
+
- `tests/e2e/conftest.py` — shared `e2e_profile_dir`, `e2e_nosession_profile`,
|
|
150
|
+
and `e2e_env` fixtures replace duplicated inline helpers in individual test files.
|
|
151
|
+
- `tests/api/transports/test_transport_timeout.py` — extracted from e2e as a
|
|
152
|
+
pure-mock integration test; also fixes `Path("/dev/null")` → `Path(os.devnull)`
|
|
153
|
+
for Windows portability.
|
|
154
|
+
- `tests/test_marker_registry.py` — invariant checks that every e2e test carries a
|
|
155
|
+
cost sub-marker, and self-tests for the auto-marker conftest hook.
|
|
156
|
+
- `docs/E2E_TESTING.md` — comprehensive e2e strategy and layer reference document.
|
|
157
|
+
|
|
158
|
+
### Fixed
|
|
159
|
+
|
|
160
|
+
- Structlog logs are now routed to stderr (via
|
|
161
|
+
`PrintLoggerFactory(file=sys.stderr)`) instead of stdout. Previously every
|
|
162
|
+
CLI event leaked onto stdout, which broke the `--json` contract for
|
|
163
|
+
programmatic callers — `json.loads(stdout)` failed because the JSON
|
|
164
|
+
payload was preceded by event-log lines. Logs are diagnostics; stdout is
|
|
165
|
+
data. No-op for human users (terminals still show logs the same way).
|
|
166
|
+
|
|
167
|
+
### Changed
|
|
168
|
+
|
|
169
|
+
- `gflow data media` now labels cloud-backed asset records as `cloud_uri_N`
|
|
170
|
+
while keeping local assets under the existing `local_path_N` labels.
|
|
171
|
+
- `gflow_cli.api.video` no longer exposes the standalone `OMNI_REFERENCE_CAP` /
|
|
172
|
+
`VEO_REFERENCE_CAP` constants. Callers that need a per-model R2V cap should
|
|
173
|
+
use `reference_cap_for(model)` (which returns `0` for `VEO_3_1_QUALITY` —
|
|
174
|
+
R2V is unsupported there). `MAX_REFERENCE_IMAGES` (= 7) is unchanged and
|
|
175
|
+
still the absolute ceiling used when the model is unknown.
|
|
176
|
+
- `GFLOW_CLI_E2E_RUN_VIDEO` default flipped from `"1"` to `"0"`. The Veo step in
|
|
177
|
+
`test_data_layer_e2e.py` is now **opt-in**: set `GFLOW_CLI_E2E_RUN_VIDEO=1` to
|
|
178
|
+
include it. This prevents accidental Veo credit burns on unattended CI runs.
|
|
179
|
+
- `pytest` `addopts` now excludes `smoke` in addition to `e2e` and `live`:
|
|
180
|
+
`not e2e and not live and not smoke`. Bare `pytest` never launches a live
|
|
181
|
+
browser session.
|
|
182
|
+
- Auto-marker conftest hook uses `item.path.parts` instead of a slash-delimited
|
|
183
|
+
string substring, fixing Windows backslash path compatibility.
|
|
184
|
+
|
|
185
|
+
## [0.9.1] — 2026-05-27
|
|
186
|
+
|
|
187
|
+
> **Locale and catalog patch release.** Hardens the headed-browser UI
|
|
188
|
+
> automation path for localized Flow profiles, fixes I2V start/end-frame
|
|
189
|
+
> attachment on non-English Chrome/Flow sessions, and repairs first-run catalog
|
|
190
|
+
> edge cases found after v0.9.0.
|
|
191
|
+
|
|
192
|
+
### Changed
|
|
193
|
+
|
|
194
|
+
- `NEW_PROJECT_SELECTORS` now covers all 14 supported locales (EN / PT / ES /
|
|
195
|
+
FR / DE / IT / NL / JA / ZH / KO / PL / RU / TR / ID) and leads with
|
|
196
|
+
locale-stable icon selectors (`add_2` Material Symbols ligature on
|
|
197
|
+
`<button>` and on `[role='button']` ARIA-role variants, plus an anchored
|
|
198
|
+
`^\+\s+\S+$` regex for `+ <word>` host elements). English-only
|
|
199
|
+
`[aria-label*='New project']` and `[aria-label*='Project']` ARIA fallbacks
|
|
200
|
+
removed.
|
|
201
|
+
`SUBMIT_BUTTON_SELECTORS` drops its English-only
|
|
202
|
+
`button[aria-label*="Create"]` fallback — the preceding `arrow_forward` icon
|
|
203
|
+
entries already cover this button in every locale. Both selector tuples are
|
|
204
|
+
now fully locale-invariant for non-English Chrome profiles. The `--lang=en-US`
|
|
205
|
+
Chromium launch arg is retained only to stabilise `IMAGE_MODEL_OPTION_SELECTORS`
|
|
206
|
+
(English product names); its removal is tracked as issue #24 Phase 5 (#94).
|
|
207
|
+
|
|
208
|
+
### Fixed
|
|
209
|
+
|
|
210
|
+
- Bare `pytest` no longer collects live/e2e tests by default. The project-wide
|
|
211
|
+
pytest `addopts` now excludes `e2e` and `live` unless callers explicitly pass
|
|
212
|
+
a different `-m` expression, and `tests/smoke/test_real_flow.py` is marked
|
|
213
|
+
with both markers so marker-filtered local and CI runs cannot accidentally
|
|
214
|
+
launch a real Flow browser session.
|
|
215
|
+
- Browser-manager PID tests no longer call the real `os.kill` while pretending
|
|
216
|
+
to be on POSIX from a Windows runner. The POSIX liveness branches are now
|
|
217
|
+
tested with mocked `os.kill`, avoiding hard interpreter/session exits during
|
|
218
|
+
local test runs.
|
|
219
|
+
|
|
220
|
+
- Running the pytest suite no longer writes fixture rows into the developer's
|
|
221
|
+
production `gflow.db` catalog. A new autouse `_isolate_settings` fixture in
|
|
222
|
+
`tests/conftest.py` redirects `GFLOW_CLI_HOME` and `GFLOW_CLI_DB_PATH` to
|
|
223
|
+
per-test `tmp_path` dirs and clears the `get_settings()` `lru_cache` before
|
|
224
|
+
and after every test, preventing the cached singleton from ever resolving to
|
|
225
|
+
a `platformdirs` production path. Closes
|
|
226
|
+
[#86](https://github.com/ffroliva/gflow-cli/issues/86).
|
|
227
|
+
|
|
228
|
+
- `gflow video i2v` no longer silently breaks on non-English Chrome profiles.
|
|
229
|
+
PR #70's structural-first `_attach_frame` cascade matched **zero** real
|
|
230
|
+
slots — its anchor selector assumed the `swap_horiz` icon used class
|
|
231
|
+
`google-symbols` (it uses `material-icons`) and the slots were `<button>`
|
|
232
|
+
(they're `<div type="button">`). Production I2V therefore relied on the
|
|
233
|
+
English-text fallback, which silently misses on any non-EN profile (pt-BR
|
|
234
|
+
shows `Inicial`/`Final`, DE shows `Anfang`/`Ende`, etc.). Replaced
|
|
235
|
+
`FRAME_SLOTS_STRUCT` with the locale-free pattern
|
|
236
|
+
`div[type='button'][aria-haspopup='dialog']` and added a `.first`-of-remaining
|
|
237
|
+
fallback for the End-frame case (after Start is attached, only one slot
|
|
238
|
+
matches and the prior `.nth(slot_index)` went out-of-bounds). Live-verified
|
|
239
|
+
with `tests/e2e/test_transports_e2e.py::test_e2e_i2v_start_end_frame_attach`
|
|
240
|
+
on `ffroliva` + `GFLOW_CLI_LOCALE=de-DE` (Chrome rendered pt-BR; both
|
|
241
|
+
non-EN). Closes [#63](https://github.com/ffroliva/gflow-cli/issues/63).
|
|
242
|
+
|
|
243
|
+
### Changed
|
|
244
|
+
|
|
245
|
+
- `gflow data media <id>` now searches across **all** profiles by default,
|
|
246
|
+
matching the cross-profile default of `gflow data list`. Pass
|
|
247
|
+
`--profile NAME` to disambiguate the rare case where the same Flow
|
|
248
|
+
media ID exists under multiple profiles (the command refuses to
|
|
249
|
+
guess and prints the list of candidate profiles, each annotated with
|
|
250
|
+
its `kind`). Closes
|
|
251
|
+
[#87](https://github.com/ffroliva/gflow-cli/issues/87).
|
|
252
|
+
|
|
253
|
+
### Fixed
|
|
254
|
+
|
|
255
|
+
- `gflow data list` no longer crashes with `no such table: assets` on a
|
|
256
|
+
missing or freshly-created catalog DB. The query path now routes through
|
|
257
|
+
`DataStore.open`, which applies schema migrations on first connect —
|
|
258
|
+
first-time users and anyone recovering from a wiped DB get an empty
|
|
259
|
+
table and exit 0 instead of a `DataStoreError`. Closes
|
|
260
|
+
[#88](https://github.com/ffroliva/gflow-cli/issues/88).
|
|
261
|
+
- `gflow auth list` no longer crashes with `UnicodeEncodeError` on Windows
|
|
262
|
+
consoles whose code page cannot encode the default-profile marker `●`
|
|
263
|
+
(cp1252 in PowerShell / cmd by default). The renderer now picks a glyph
|
|
264
|
+
safe for the active `sys.stdout.encoding` — `●` on UTF-8, ASCII `*` on
|
|
265
|
+
cp1252 / ascii / latin-1 / unknown. Closes [#82](https://github.com/ffroliva/gflow-cli/issues/82).
|
|
266
|
+
|
|
267
|
+
### Documentation
|
|
268
|
+
|
|
269
|
+
- `PLAN.md` refreshed to reflect develop state through v0.9.0 — marks Phase 6
|
|
270
|
+
(data layer) shipped via PR #58 + #78 + #81, Phase 7 Issue #24 Phase 2
|
|
271
|
+
shipped via PR #70, Phase B I2V/R2V shipped via PR #48, and resolves the
|
|
272
|
+
duplicate Phase 7 numbering (pluggable storage renumbered to Phase 8).
|
|
273
|
+
|
|
10
274
|
## [0.9.0] — 2026-05-25
|
|
11
275
|
|
|
12
276
|
> **Maturity & Visibility release.** Surfaces the SQLite catalog (PR #52/#58)
|
|
@@ -945,7 +1209,9 @@ shell-script template that branches on these codes.
|
|
|
945
1209
|
|
|
946
1210
|
First skeleton. Not functional end-to-end yet.
|
|
947
1211
|
|
|
948
|
-
[Unreleased]: https://github.com/ffroliva/gflow-cli/compare/v0.
|
|
1212
|
+
[Unreleased]: https://github.com/ffroliva/gflow-cli/compare/v0.10.0...HEAD
|
|
1213
|
+
[0.10.0]: https://github.com/ffroliva/gflow-cli/compare/v0.9.1...v0.10.0
|
|
1214
|
+
[0.9.1]: https://github.com/ffroliva/gflow-cli/compare/v0.9.0...v0.9.1
|
|
949
1215
|
[0.9.0]: https://github.com/ffroliva/gflow-cli/compare/v0.8.1...v0.9.0
|
|
950
1216
|
[0.8.1]: https://github.com/ffroliva/gflow-cli/compare/v0.8.0...v0.8.1
|
|
951
1217
|
[0.8.0]: https://github.com/ffroliva/gflow-cli/compare/v0.7.0...v0.8.0
|
|
@@ -39,6 +39,11 @@ def test_parse_uuid_from_url(): ...
|
|
|
39
39
|
async def test_upload_returns_asset(): ...
|
|
40
40
|
|
|
41
41
|
@pytest.mark.e2e # Hits the real Flow API. Requires GFLOW_CLI_E2E_PROFILE env var.
|
|
42
|
+
@pytest.mark.e2e_image # Cost sub-marker: spends ~1 Imagen credit.
|
|
43
|
+
async def test_full_t2i_roundtrip(): ...
|
|
44
|
+
|
|
45
|
+
@pytest.mark.e2e
|
|
46
|
+
@pytest.mark.e2e_video # Cost sub-marker: spends ~1 Veo credit (most expensive).
|
|
42
47
|
async def test_full_i2v_roundtrip(): ...
|
|
43
48
|
```
|
|
44
49
|
|
|
@@ -46,10 +51,23 @@ CI runs `unit` + `integration` on every push. `e2e` tests require a live authent
|
|
|
46
51
|
|
|
47
52
|
```bash
|
|
48
53
|
export GFLOW_CLI_E2E_PROFILE=<profile-name> # name of a logged-in profile
|
|
49
|
-
|
|
54
|
+
|
|
55
|
+
# Zero-credit sanity check (auth + health)
|
|
56
|
+
uv run pytest -m e2e_auth -v
|
|
57
|
+
|
|
58
|
+
# Single image (1 Imagen credit)
|
|
59
|
+
uv run pytest -m "e2e_image and not e2e_batch" -v
|
|
60
|
+
|
|
61
|
+
# Full regression (all credits)
|
|
62
|
+
GFLOW_CLI_E2E_RUN_VIDEO=1 uv run pytest -m e2e -v
|
|
50
63
|
```
|
|
51
64
|
|
|
52
|
-
E2e tests spend real Veo/Imagen credits
|
|
65
|
+
E2e tests spend real Veo/Imagen credits. Video tests default to opt-out — set
|
|
66
|
+
`GFLOW_CLI_E2E_RUN_VIDEO=1` to include them. Run the full suite on `develop`
|
|
67
|
+
before opening a release PR to `main`.
|
|
68
|
+
|
|
69
|
+
See [docs/E2E_TESTING.md](docs/E2E_TESTING.md) for the complete layer reference,
|
|
70
|
+
cost table, and run commands.
|
|
53
71
|
|
|
54
72
|
### Coverage targets
|
|
55
73
|
|
|
@@ -64,13 +82,19 @@ E2e tests spend real Veo/Imagen credits — run them on `develop` before opening
|
|
|
64
82
|
|
|
65
83
|
```bash
|
|
66
84
|
uv run python scripts/ci/check_repo_hygiene.py # artefact + path hygiene
|
|
85
|
+
uv run python scripts/ci/check_doc_links.py # internal Markdown links
|
|
67
86
|
uv run ruff check src tests # lint
|
|
68
87
|
uv run ruff format src tests # auto-format
|
|
69
88
|
uv run pyright src # type-check (strict on src/gflow_cli/)
|
|
70
89
|
uv run pytest -q --cov=gflow_cli # tests + coverage
|
|
71
90
|
```
|
|
72
91
|
|
|
73
|
-
CI runs all
|
|
92
|
+
CI runs all six on every push. Documentation is part of the merge gate: update
|
|
93
|
+
the relevant docs for behavior, workflow, configuration, architecture, or
|
|
94
|
+
operator-facing changes. If no documentation change is needed, state that in
|
|
95
|
+
the PR validation checklist.
|
|
96
|
+
|
|
97
|
+
Install local pre-commit hooks (recommended):
|
|
74
98
|
|
|
75
99
|
```bash
|
|
76
100
|
pip install pre-commit && pre-commit install
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# GEMINI.md
|
|
2
|
+
|
|
3
|
+
> Project memory hub for **Gemini CLI**. The universal coding-agent rules for any tool (Cursor, Codex, Aider, Gemini CLI, etc.) live in [AGENTS.md](AGENTS.md) — this file carries Gemini-specific session protocol only.
|
|
4
|
+
|
|
5
|
+
## What this project is
|
|
6
|
+
|
|
7
|
+
`gflow-cli` is an unofficial Python CLI that drives [Google Flow](https://labs.google/fx/tools/flow) (Veo image-to-video, Imagen text-to-image) from the terminal by reverse-engineering Flow's private REST API. See [README.md](README.md) for the user-facing overview.
|
|
8
|
+
|
|
9
|
+
## On every session start
|
|
10
|
+
|
|
11
|
+
1. Read **[AGENTS.md](AGENTS.md)** — universal rules every agent must follow.
|
|
12
|
+
2. Read **[docs/INDEX.md](docs/INDEX.md)** — routing layer for all project docs and commands.
|
|
13
|
+
3. Pull deeper context on demand:
|
|
14
|
+
- Starting a feature → `/gflow:plan`
|
|
15
|
+
- Touching auth or reCAPTCHA → `/gflow:known-issues`
|
|
16
|
+
- Cutting a release → `/gflow:release`
|
|
17
|
+
- Before any commit → `/gflow:check`
|
|
18
|
+
|
|
19
|
+
## Gemini-specific
|
|
20
|
+
|
|
21
|
+
- Use specialized skills when relevant (e.g., `find-docs` for library research, `pr-council-review` for PR audits).
|
|
22
|
+
- Maintain memory via the `mcp-mempalace` tool if available.
|
|
23
|
+
- Prioritize **turn efficiency** and **high-signal output**.
|
|
24
|
+
|
|
25
|
+
## Active phase
|
|
26
|
+
|
|
27
|
+
See [PLAN.md](PLAN.md) or run `/gflow:plan` for the current detailed plan.
|