gflow-cli 0.15.1__tar.gz → 0.17.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.15.1 → gflow_cli-0.17.0}/.claude/commands/gflow/check.md +7 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/.claude/commands/gflow/release.md +19 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/.gitignore +3 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/AGENTS.md +1 -1
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/CHANGELOG.md +28 -1
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/CLAUDE.md +1 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/KNOWN_ISSUES.md +75 -3
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/PKG-INFO +2 -1
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/RELEASE.md +25 -10
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/docs/AUTHENTICATION.md +21 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/docs/CHARACTER.md +2 -1
- gflow_cli-0.17.0/docs/IMAGE_UPSCALE_RECON.md +115 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/docs/INDEX.md +4 -1
- gflow_cli-0.17.0/docs/LIVE_VERIFICATION_v0.16.0.md +77 -0
- gflow_cli-0.17.0/docs/LIVE_VERIFICATION_v0.17.0.md +94 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/docs/MOVIE.md +7 -4
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/docs/PROJECT_STATUS.md +7 -2
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/docs/USAGE.md +38 -0
- gflow_cli-0.17.0/docs/superpowers/plans/2026-06-12-issue-174-library-ui-attach/PLAN.md +186 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/pyproject.toml +2 -1
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/scripts/ci/check_repo_hygiene.py +52 -1
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/scripts/dev/active_plan.py +7 -0
- gflow_cli-0.17.0/scripts/dev/spike_image_upscale_capture.py +382 -0
- gflow_cli-0.17.0/scripts/dev/spike_image_upscale_drive.py +383 -0
- gflow_cli-0.17.0/scripts/dev/spike_image_upscale_recaptcha_action.py +188 -0
- gflow_cli-0.17.0/scripts/dev/spike_image_upscale_rest_probe.py +277 -0
- gflow_cli-0.17.0/scripts/dev/spike_issue170_picker_locale_recon.py +234 -0
- gflow_cli-0.17.0/scripts/dev/spike_issue174_library_ui_recon.py +445 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/scripts/dev/spike_movie_attach_payload.py +13 -1
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/skills/scenario/SKILL.md +7 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/src/gflow_cli/__init__.py +1 -1
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/src/gflow_cli/api/client.py +137 -0
- gflow_cli-0.17.0/src/gflow_cli/api/image_upscale.py +159 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/src/gflow_cli/api/routes.py +4 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/src/gflow_cli/api/transports/ui_automation.py +94 -3
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/src/gflow_cli/api/transports/ui_automation_video.py +120 -18
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/src/gflow_cli/auth/__init__.py +8 -9
- gflow_cli-0.17.0/src/gflow_cli/auth/cookies.py +159 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/src/gflow_cli/auth/real_chrome.py +24 -3
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/src/gflow_cli/auth/verification.py +108 -8
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/src/gflow_cli/cli_image.py +176 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/src/gflow_cli/errors.py +31 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/src/gflow_cli/exceptions.py +1 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/src/gflow_cli/paths.py +11 -0
- gflow_cli-0.17.0/tests/api/test_client_upscale.py +169 -0
- gflow_cli-0.17.0/tests/api/test_image_upscale.py +153 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/api/transports/test_ui_automation.py +156 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/api/transports/test_ui_automation_video.py +174 -13
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/auth/strategies/test_strategies.py +44 -3
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/auth/test_verification.py +276 -0
- gflow_cli-0.17.0/tests/cli/test_cli_image_upscale.py +140 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/e2e/conftest.py +10 -4
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/e2e/test_auth_verification_e2e.py +33 -8
- gflow_cli-0.17.0/tests/features/image_upscale.feature +29 -0
- gflow_cli-0.17.0/tests/features/locale_picker_include.feature +25 -0
- gflow_cli-0.17.0/tests/features/test_image_upscale_steps.py +130 -0
- gflow_cli-0.17.0/tests/features/test_locale_picker_include_steps.py +211 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/scripts/test_check_repo_hygiene.py +45 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/test_errors.py +14 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/uv.lock +129 -1
- gflow_cli-0.15.1/.continue-here.md +0 -118
- gflow_cli-0.15.1/PR162_MOVIE_CHARACTER_REVIEW.md +0 -137
- gflow_cli-0.15.1/docs/superpowers/2026-05-17-issue-15-handover.md +0 -59
- gflow_cli-0.15.1/docs/superpowers/character-scenario.md +0 -140
- gflow_cli-0.15.1/docs/superpowers/plans/2026-06-01-governance-enforcement-advisory/PLAN.md +0 -271
- gflow_cli-0.15.1/docs/superpowers/plans/2026-06-04-character-create-recording.md +0 -428
- gflow_cli-0.15.1/docs/superpowers/plans/2026-06-06-movie-p0-asyncio-hotfix.md +0 -223
- gflow_cli-0.15.1/docs/superpowers/plans/2026-06-06-movie-p1-composition-manifest.md +0 -1208
- gflow_cli-0.15.1/docs/superpowers/plans/2026-06-06-movie-p2-native-identity-voice.md +0 -612
- gflow_cli-0.15.1/docs/superpowers/specs/2026-06-06-movie-consistency-design.md +0 -310
- gflow_cli-0.15.1/docs/superpowers/verifications/2026-05-11-phase-4-stage-g.md +0 -123
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/.claude/README.md +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/.claude/commands/gflow/active.md +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/.claude/commands/gflow/branch-review.md +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/.claude/commands/gflow/changelog.md +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/.claude/commands/gflow/doc-review.md +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/.claude/commands/gflow/known-issues.md +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/.claude/commands/gflow/next.md +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/.claude/commands/gflow/plan.md +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/.claude/commands/gflow/pr-council-review.md +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/.claude/commands/gflow/predict.md +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/.claude/commands/gflow/scenario.md +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/.claude/commands/gflow/status.md +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/.env.template +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/.gitattributes +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/.github/CODEOWNERS +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/.github/copilot-instructions.md +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/.github/dependabot.yml +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/.github/workflows/ci.yml +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/.github/workflows/external-pr-triage.yml +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/.github/workflows/governance-advisory.yml +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/.github/workflows/governance-benchmark.yml +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/.github/workflows/release.yml +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/.gitleaks.toml +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/.pre-commit-config.yaml +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/.secrets.baseline +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/CONFIGURATION.md +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/CONTRIBUTING.md +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/DISCLAIMER.md +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/GEMINI.md +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/LICENSE +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/PLAN.md +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/README.md +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/ROADMAP.md +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/conftest.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/docker-compose.yml +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/docs/AGENT_GUIDE.md +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/docs/ARCHITECTURE.md +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/docs/CHARACTER_RECON.md +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/docs/CONFIGURATION.md +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/docs/DATA_LAYER.md +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/docs/DEBUGGING.md +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/docs/DEMOS.md +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/docs/DEVELOPMENT.md +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/docs/E2E_TESTING.md +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/docs/EXTERNAL_STORAGE.md +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/docs/GITHUB.md +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/docs/GOVERNANCE_BENCHMARK.md +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/docs/LIVE_VERIFICATION_data_layer.md +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/docs/LIVE_VERIFICATION_image_batch.md +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/docs/LIVE_VERIFICATION_v0.10.0.md +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/docs/LIVE_VERIFICATION_v0.11.0.md +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/docs/LIVE_VERIFICATION_v0.12.0.md +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/docs/LIVE_VERIFICATION_v0.13.0.md +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/docs/LIVE_VERIFICATION_v0.7.0.md +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/docs/LIVE_VERIFICATION_v0.8.1.md +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/docs/LIVE_VERIFICATION_v0.9.0.md +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/docs/LIVE_VERIFICATION_v0.9.1.md +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/docs/LIVE_VERIFICATION_video_download.md +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/docs/SECURITY.md +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/docs/USER_GUIDE.md +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/docs/assets/demo-split-pf.gif +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/docs/assets/example-run.gif +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/docs/schemas/movie-handoff.schema.json +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/examples/README.md +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/examples/batch_from_config.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/examples/multi_prompt_t2i.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/examples/sample_config.json +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/examples/sample_prompts.txt +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/examples/single_image_t2i.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/examples/workflow_chain.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/llms.txt +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/samples/README.md +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/samples/captured/01_upload_image.json +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/samples/captured/02_batchAsyncGenerateVideoText.json +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/samples/captured/03_batchCheckAsyncVideoGenerationStatus.json +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/samples/captured/04_archive_workflow.json +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/samples/captured/05_createProject.json +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/samples/captured/06_batchGenerateImages.json +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/samples/captured/07_batchGenerateImages_seeded.json +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/samples/captured/08_batchAsyncGenerateVideoStartAndEndImage.json +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/samples/captured/09_batchAsyncGenerateVideoReferenceImages.json +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/samples/captured/10_batchCheckAsyncVideoGenerationStatus_successful.json +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/samples/captured/11_batchCheckAsyncVideoGenerationStatus_failed.json +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/samples/captured/12_create_scene.json +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/samples/captured/13_sceneWorkflows_update.json +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/samples/captured/14_get_scene_workflows.json +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/samples/captured/15_commit_flowWorkflow.json +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/scripts/ci/check_doc_links.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/scripts/ci/check_materiality.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/scripts/debug_editor.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/scripts/debug_gen_settings.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/scripts/debug_settings.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/scripts/dev/_recording_client.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/scripts/dev/_spike_common.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/scripts/dev/capture_i2v_frame_slots_dom.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/scripts/dev/capture_i2v_intercept_submit.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/scripts/dev/capture_i2v_model_select_repro.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/scripts/dev/capture_i2v_post_bind_state.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/scripts/dev/capture_image_add_media_dom.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/scripts/dev/capture_locale_invariants.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/scripts/dev/cdp_drive_and_probe.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/scripts/dev/character_create_spike.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/scripts/dev/character_create_spike_v2.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/scripts/dev/dump_character_selectors.js +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/scripts/dev/make_project.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/scripts/dev/materiality_backtest.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/scripts/dev/monitor_pr_38.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/scripts/dev/patch_character.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/scripts/dev/record_flow_capture.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/scripts/dev/skillopt/README.md +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/scripts/dev/skillopt/harness.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/scripts/dev/skillopt/tasks.json +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/scripts/dev/spike_char_editor_dom.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/scripts/dev/spike_char_gen_capture.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/scripts/dev/spike_movie_entity_recon.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/scripts/dev/spike_movie_gen_capture.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/scripts/dev/spike_movie_picker_select.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/scripts/dev/spike_movie_voice_list.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/scripts/dev/spike_patch_entity.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/scripts/diag/README.md +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/scripts/diag/capture_flow_traffic.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/scripts/diag/memory_profile.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/scripts/diag/recaptcha_mint.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/scripts/record_demo.ps1 +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/scripts/smoke_image.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/scripts/smoke_real_chrome_image.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/scripts/smoke_video_editor.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/scripts/smoke_worker_style.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/scripts/verify_chrome_auth_viability.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/skills/README.md +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/skills/gflow-cli/SKILL.md +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/skills/plan/SKILL.md +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/skills/pr-council-review/SKILL.md +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/skills/predict/SKILL.md +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/skills/status/SKILL.md +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/sonar-project.properties +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/src/gflow_cli/__main__.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/src/gflow_cli/_cli_helpers.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/src/gflow_cli/api/__init__.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/src/gflow_cli/api/_retry.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/src/gflow_cli/api/_sapisidhash.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/src/gflow_cli/api/character.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/src/gflow_cli/api/dto.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/src/gflow_cli/api/image.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/src/gflow_cli/api/recaptcha.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/src/gflow_cli/api/scene.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/src/gflow_cli/api/transports/__init__.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/src/gflow_cli/api/transports/_common.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/src/gflow_cli/api/transports/_fingerprint.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/src/gflow_cli/api/transports/base.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/src/gflow_cli/api/transports/experimental/__init__.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/src/gflow_cli/api/transports/experimental/bearer.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/src/gflow_cli/api/transports/experimental/evaluate_fetch.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/src/gflow_cli/api/transports/experimental/sapisidhash.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/src/gflow_cli/api/video.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/src/gflow_cli/auth/base.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/src/gflow_cli/auth/factory.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/src/gflow_cli/auth/internal_chromium.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/src/gflow_cli/auth/strategies.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/src/gflow_cli/browser_manager.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/src/gflow_cli/chain.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/src/gflow_cli/chain_manifest.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/src/gflow_cli/cli.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/src/gflow_cli/cli_character.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/src/gflow_cli/cli_data.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/src/gflow_cli/cli_models.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/src/gflow_cli/cli_movie.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/src/gflow_cli/cli_run.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/src/gflow_cli/cli_scene.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/src/gflow_cli/cli_video.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/src/gflow_cli/composition.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/src/gflow_cli/config.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/src/gflow_cli/data/__init__.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/src/gflow_cli/data/chain_repo.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/src/gflow_cli/data/migrations/0001_initial.sql +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/src/gflow_cli/data/migrations/0002_add_cloud_storage.sql +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/src/gflow_cli/data/migrations/0003_add_scene_tables.sql +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/src/gflow_cli/data/migrations/0004_add_scene_output_path.sql +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/src/gflow_cli/data/migrations/0005_add_chain_links.sql +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/src/gflow_cli/data/migrations/0006_add_operations_metadata.sql +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/src/gflow_cli/data/migrations/__init__.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/src/gflow_cli/data/models.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/src/gflow_cli/data/queries.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/src/gflow_cli/data/recorder.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/src/gflow_cli/data/redaction.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/src/gflow_cli/data/repository.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/src/gflow_cli/data/store.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/src/gflow_cli/image_batch.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/src/gflow_cli/json_output.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/src/gflow_cli/manifest.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/src/gflow_cli/media.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/src/gflow_cli/movie_manifest.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/src/gflow_cli/observability.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/src/gflow_cli/profile_store.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/src/gflow_cli/services/__init__.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/src/gflow_cli/services/character_create.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/src/gflow_cli/storage.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tasks/lessons.md +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/test_assets/sample_batch.json +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/test_assets/sample_batch.tsv +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/test_assets/sample_batch_invalid.tsv +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/__init__.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/api/__init__.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/api/fixtures/character_gen_response.json +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/api/fixtures/patch_entity_response.json +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/api/test_aisandbox_auth_error.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/api/test_aisandbox_auth_headers.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/api/test_bearer_redaction.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/api/test_character.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/api/test_client.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/api/test_client_character.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/api/test_client_delete_characters.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/api/test_client_generate_character.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/api/test_client_image.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/api/test_client_launch_kwargs.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/api/test_client_patch_entity.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/api/test_client_scene.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/api/test_concurrency.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/api/test_dto.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/api/test_image.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/api/test_image_dto.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/api/test_post_json_aisandbox_auth.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/api/test_recaptcha.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/api/test_retry.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/api/test_routes.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/api/test_routes_character.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/api/test_routes_scene.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/api/test_sapisidhash_helper.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/api/test_scene_models.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/api/test_video.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/api/test_video_request.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/api/transports/__init__.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/api/transports/test_base.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/api/transports/test_bearer.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/api/transports/test_common.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/api/transports/test_evaluate_fetch.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/api/transports/test_factory.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/api/transports/test_fingerprint.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/api/transports/test_sapisidhash.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/api/transports/test_transport_timeout.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/api/transports/test_ui_automation_batch.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/api/transports/test_ui_automation_image_mode.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/api/transports/test_ui_character_editor.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/auth/strategies/test_factory.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/cli/__init__.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/cli/test_cli_auth_list.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/cli/test_cli_character.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/cli/test_cli_character_create.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/cli/test_cli_data.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/cli/test_cli_image.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/cli/test_cli_image_seed_removed.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/cli/test_cli_models.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/cli/test_cli_movie.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/cli/test_cli_run.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/cli/test_cli_scene.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/cli/test_cli_video.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/cli/test_cli_video_chain.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/cli/test_error_handling.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/cli/test_helpers.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/cli/test_movie_manifest.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/cli/test_t2i_multi_prompt.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/composition/test_character.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/composition/test_compose_prompt.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/composition/test_handoff.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/conftest.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/data/__init__.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/data/test_chain_repo.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/data/test_find_incomplete_character.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/data/test_models.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/data/test_packaging.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/data/test_recorder.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/data/test_recorder_character.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/data/test_redaction.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/data/test_repository.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/data/test_scene_persistence.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/data/test_settings_and_errors.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/data/test_store_migrations.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/dev/test_record_flow_capture.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/dev/test_recording_client.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/e2e/__init__.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/e2e/test_aisandbox_auth_live.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/e2e/test_chain_e2e.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/e2e/test_character_create_e2e.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/e2e/test_data_layer_e2e.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/e2e/test_i2v_flags_e2e.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/e2e/test_image_batch_e2e.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/e2e/test_image_i2i_ref_cap_e2e.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/e2e/test_json_output_e2e.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/e2e/test_locale_selectors_e2e.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/e2e/test_scene_compose_live.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/e2e/test_transports_e2e.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/e2e/test_video_r2v_ref_cap_e2e.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/e2e/test_video_t2v_e2e.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/features/__init__.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/features/auth.feature +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/features/auth_login.feature +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/features/character_create.feature +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/features/character_read.feature +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/features/conftest.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/features/image.feature +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/features/test_auth_login_steps.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/features/test_auth_steps.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/features/test_character_create_steps.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/features/test_character_read_steps.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/features/test_image_steps.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/features/test_step_collision_guard.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/features/test_video_chain_steps.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/features/video_chain.feature +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/fixtures/__init__.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/fixtures/seeded_catalog.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/image_batch/__init__.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/image_batch/test_image_manifest.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/image_batch/test_observability_events.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/integration/__init__.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/integration/conftest.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/integration/constants.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/integration/test_storage_gcs.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/integration/test_storage_s3.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/scripts/test_capture_locale_invariants.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/scripts/test_check_materiality.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/scripts/test_materiality_backtest.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/services/__init__.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/services/test_character_create_redaction.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/services/test_character_create_saga.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/services/test_character_gen_no_direct_post.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/smoke/__init__.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/smoke/test_profile_account_smoke.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/smoke/test_real_flow.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/test_auth.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/test_browser_manager.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/test_chain.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/test_chain_manifest.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/test_cli_data.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/test_config.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/test_conftest_isolation.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/test_data_queries.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/test_documentation_gate.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/test_errors_403.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/test_json_output.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/test_manifest.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/test_marker_registry.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/test_media.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/test_observability.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/test_paths.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/test_profile_store.py +0 -0
- {gflow_cli-0.15.1 → gflow_cli-0.17.0}/tests/test_smoke.py +0 -0
|
@@ -50,3 +50,10 @@ If the coverage run crashes the current MCP/sandbox session with `Connection clo
|
|
|
50
50
|
same marker-filtered suite in smaller chunks without coverage and rely on CI for the coverage XML.
|
|
51
51
|
Project pytest defaults already exclude `e2e` and `live`; those markers are explicit,
|
|
52
52
|
credit-spending gates and must be requested with a separate `-m e2e` / `-m live` command.
|
|
53
|
+
|
|
54
|
+
**Windows agent sessions:** `uv run pytest` is unreliable — invoke
|
|
55
|
+
`.venv/Scripts/python.exe -m pytest` directly, and prefix Python invocations with
|
|
56
|
+
`PYTHONUTF8=1` when output contains non-ASCII. The unscoped full-coverage sweep
|
|
57
|
+
(step 4) can OOM locally (exit 137 / SIGKILL): run the suites scoped to the dirs you
|
|
58
|
+
touched and trust CI for the full coverage gate — **a green full-suite CI run on the
|
|
59
|
+
same tree (e.g. the just-merged PR) satisfies step 4 for release purposes.**
|
|
@@ -70,6 +70,19 @@ memory) or the release branch will hit conflicts on `pyproject.toml` / `__init__
|
|
|
70
70
|
|
|
71
71
|
Run `/gflow:check` — all gates must pass. Abort if any fail.
|
|
72
72
|
|
|
73
|
+
**4b. Live-verify the release's user-facing features (REQUIRED gate).**
|
|
74
|
+
|
|
75
|
+
For every new/changed user-facing feature in this release, exercise it against
|
|
76
|
+
live Flow (credit-free wherever possible — image gen, entity attach, upscale, and
|
|
77
|
+
scene/timeline ops cost no Veo credits) and write the evidence to
|
|
78
|
+
`docs/LIVE_VERIFICATION_v<NEW_VERSION>.md` using the 5-layer ledger (file count +
|
|
79
|
+
magic bytes + dimensions/shape + structlog invariants + a user-confirmable
|
|
80
|
+
artifact). Add it to the "what was live-verified" entry in `docs/INDEX.md`. This
|
|
81
|
+
doc shipped for every release v0.7.0→v0.13.0, then lapsed for v0.14.0–v0.15.1 —
|
|
82
|
+
which is why it is now an explicit gate. If a feature genuinely cannot be verified
|
|
83
|
+
this cycle, record that and the reason in the doc; never silently omit it. Stage
|
|
84
|
+
the doc into the release-prep commit (step 11).
|
|
85
|
+
|
|
73
86
|
**5. Create a release branch off `develop`.**
|
|
74
87
|
|
|
75
88
|
```bash
|
|
@@ -116,6 +129,12 @@ rg -n "__version__|<OLD_VERSION>|version assertion" tests src pyproject.toml
|
|
|
116
129
|
|
|
117
130
|
Run `/gflow:doc-review` — audit all version refs, INDEX completeness, evidence files, skill files, CHANGELOG footer, and memory files. Fix every **FAIL** before continuing. Fold all discovered fixes into the release prep commit.
|
|
118
131
|
|
|
132
|
+
Also **consolidate shipped planning artifacts** here: extract any durable patterns
|
|
133
|
+
into auto-memory, then remove the now-shipped `docs/superpowers/` plan / spec /
|
|
134
|
+
verification files (keep only in-flight work). `check_repo_hygiene.py` enforces the
|
|
135
|
+
root-doc allowlist, so a stray review doc or session marker left at the repo root
|
|
136
|
+
will fail the gate.
|
|
137
|
+
|
|
119
138
|
**11. Commit the release prep.**
|
|
120
139
|
|
|
121
140
|
```bash
|
|
@@ -66,6 +66,9 @@ test_assets/debug_*/
|
|
|
66
66
|
# Phase-2 live-spike capture outputs — NEVER commit (may contain real API payloads)
|
|
67
67
|
scripts/dev/_spike_out/
|
|
68
68
|
|
|
69
|
+
# Agent session marker — machine/session-local handoff state, regenerated per run
|
|
70
|
+
.continue-here.md
|
|
71
|
+
|
|
69
72
|
# Live Flow traffic captures — NEVER commit (contain real Bearer tokens / API keys).
|
|
70
73
|
# Diagnostic scripts MUST default-write here, NOT to samples/captured/.
|
|
71
74
|
# Sanitised reference samples (no secrets) can still live under samples/captured/.
|
|
@@ -56,7 +56,7 @@ Or invoke the wrapper: `/gflow:check`.
|
|
|
56
56
|
|
|
57
57
|
- Type hints everywhere; `pyright` strict on `src/gflow_cli`.
|
|
58
58
|
- Structured logging only (`structlog`) — **never** raw `print()` or `import logging` in `src/`.
|
|
59
|
-
- Errors as RFC 9457 Problem Details with stable per-class exit codes (3–
|
|
59
|
+
- Errors as RFC 9457 Problem Details with stable per-class exit codes (3–22, e.g. 16 is the `DataStoreError` family, 19 `SceneConcatError`, 20 `FrameExtractionError`, 21 `ChainPartialError`, 22 `UpscaleUnavailableError`). See `src/gflow_cli/errors.py::EXIT_CODE_MAP` for the complete mapping.
|
|
60
60
|
- 100-char line length, `ruff` configured. Imports sorted by `ruff` (isort rules).
|
|
61
61
|
|
|
62
62
|
## PR instructions
|
|
@@ -7,6 +7,31 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.17.0] — 2026-06-12
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- Added `verify_flow_profile` in `gflow_cli.auth.verification` using `browser_cookie3` and `httpx` to verify sessions directly from the Chrome cookie store (fast path), with a marker-gated Playwright fallback for encrypted/locked stores. `RealChromeStrategy` now writes the Chrome marker before verification (the fallback reads it) and, on failure, rolls back only a speculative write — a marker that legitimately pre-existed (a previously-verified chrome profile) survives a transient probe failure, and an interrupted verification never leaves an unverified profile claiming the chrome strategy. Cookie extraction is centralised in the new `gflow_cli.auth.cookies` module.
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
|
|
18
|
+
- `gflow_cli.auth.cookies._get_chrome_cookies3` now catches `RuntimeError` (Windows DPAPI failure — `RuntimeError('Failed to decrypt the cipher text with DPAPI')`) in addition to `browser_cookie3.BrowserCookieError`, and re-raises both as `PermissionError` so the Playwright fallback is triggered instead of propagating an unhandled exception.
|
|
19
|
+
- `verify_flow_profile` now retries transient HTTP failures (429/503/504) and network errors up to `_MAX_ATTEMPTS` times with exponential backoff, matching the retry behaviour of the existing Playwright-based `verify_flow_session`.
|
|
20
|
+
|
|
21
|
+
### Changed
|
|
22
|
+
|
|
23
|
+
- Entity-attach `WireFormatError` failures (exit 7) now carry a remediation hint pointing at Flow's new full-page media-library UI rollout ([#174](https://github.com/ffroliva/gflow-cli/issues/174)) — affected accounts can stage entities via the include action but the submit never carries `referenceEntities`; the error now explains how to tell which UI an account has and where to follow the fix, instead of the generic file-a-bug hint. Both backstops also emit an `entity_attach_context` discovery field (`video`/`image`) for drift telemetry. New KNOWN_ISSUES entry documents the rollout
|
|
24
|
+
|
|
25
|
+
## [0.16.0] — 2026-06-12
|
|
26
|
+
|
|
27
|
+
### Fixed
|
|
28
|
+
|
|
29
|
+
- **`--reference-entity` no longer fails on non-Portuguese Flow accounts** ([#170](https://github.com/ffroliva/gflow-cli/issues/170)) — the resource-picker include selectors hardcoded the pt-BR caption "Incluir no comando"; they are now locale-free tier cascades (context-menu `add`-ligature anchor + pt/ru/en text fallback), fixing `gflow image t2i --reference-entity`, movie R2V entity attach, and Vozes voice attach for every account language. Failures are now typed (`TransportTimeoutError`, exit 9) with a locale-neutral remediation hint, the matched selector tier is logged (`include_selector_tier`) for drift telemetry, and a new image-side submit backstop raises `WireFormatError` (exit 7) if a staged character never reaches the wire instead of silently returning a text-only generation. Thanks @papushin7987 for the live-verified report
|
|
30
|
+
|
|
31
|
+
### Added
|
|
32
|
+
|
|
33
|
+
- **`gflow image upscale <mediaId> --scale 2k|4k`** — upscale a platform-generated image to 2K or 4K (Flow's download-menu 1K/2K/4K options) and save it locally; credit-free. The owning project is resolved from the local catalog (or pass `--project` for images gflow didn't record). 4K requires a Flow Ultra subscription — a non-Ultra 4K request fails fast with exit code 22 (`UpscaleUnavailableError`) rather than a generic 403. Reverse-engineered wire documented in [docs/IMAGE_UPSCALE_RECON.md](docs/IMAGE_UPSCALE_RECON.md); live-verified end-to-end (issue #171)
|
|
34
|
+
|
|
10
35
|
## [0.15.1] — 2026-06-10
|
|
11
36
|
|
|
12
37
|
### Changed
|
|
@@ -1484,7 +1509,9 @@ shell-script template that branches on these codes.
|
|
|
1484
1509
|
|
|
1485
1510
|
First skeleton. Not functional end-to-end yet.
|
|
1486
1511
|
|
|
1487
|
-
[Unreleased]: https://github.com/ffroliva/gflow-cli/compare/v0.
|
|
1512
|
+
[Unreleased]: https://github.com/ffroliva/gflow-cli/compare/v0.17.0...HEAD
|
|
1513
|
+
[0.17.0]: https://github.com/ffroliva/gflow-cli/compare/v0.16.0...v0.17.0
|
|
1514
|
+
[0.16.0]: https://github.com/ffroliva/gflow-cli/compare/v0.15.1...v0.16.0
|
|
1488
1515
|
[0.15.1]: https://github.com/ffroliva/gflow-cli/compare/v0.15.0...v0.15.1
|
|
1489
1516
|
[0.15.0]: https://github.com/ffroliva/gflow-cli/compare/v0.14.0...v0.15.0
|
|
1490
1517
|
[0.14.0]: https://github.com/ffroliva/gflow-cli/compare/v0.13.0...v0.14.0
|
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
- Slash commands live under `.claude/commands/gflow/` (all prefixed `/gflow:`).
|
|
23
23
|
- Skills under `skills/` are auto-discoverable; `gflow-cli` ships its own at [`skills/gflow-cli/SKILL.md`](skills/gflow-cli/SKILL.md).
|
|
24
24
|
- Auto-memory at `~/.claude/projects/C--development-github-gflow-cli/memory/MEMORY.md` carries cross-session feedback and project state.
|
|
25
|
+
- **Worktrees:** the native `EnterWorktree` tool branches from `origin/main` (the default branch). Feature work integrates via `develop` — after entering a fresh worktree, immediately `git switch -c <type>/<name> origin/develop` and delete the auto-created `worktree-*` branch. On Windows, worktree removal can fail on a file lock (the worktree's `.venv`); `git worktree prune` + manual delete later is fine.
|
|
25
26
|
|
|
26
27
|
## MCP GitHub tool — PR body rule (non-negotiable)
|
|
27
28
|
|
|
@@ -14,6 +14,55 @@ Living list of behaviour that's broken, surprising, or limited by design — alo
|
|
|
14
14
|
|
|
15
15
|
## Open
|
|
16
16
|
|
|
17
|
+
### Flow's new full-page media-library UI breaks entity attach (A/B rollout)
|
|
18
|
+
|
|
19
|
+
- **Status:** **Open** — Flow-side staged rollout; tracked in
|
|
20
|
+
[#174](https://github.com/ffroliva/gflow-cli/issues/174)
|
|
21
|
+
- **Severity:** High · **Affects:** `gflow image t2i --reference-entity` and
|
|
22
|
+
movie R2V entity attach on accounts that received the new UI, any locale
|
|
23
|
+
|
|
24
|
+
Flow is A/B-rolling a new full-page media-library UI: clicking **Add Media**
|
|
25
|
+
in the composer **navigates to a library page** (sidebar: All media /
|
|
26
|
+
Characters / Scenes / Tools, with a floating quick-create composer) instead of
|
|
27
|
+
opening the resource-picker dialog. On affected accounts the right-click
|
|
28
|
+
include action still lands (a chip appears), **but the staged entity never
|
|
29
|
+
reaches the submit** — the request carries no `referenceEntities`, so the
|
|
30
|
+
submit backstops raise `WireFormatError` (**exit 7**) instead of silently
|
|
31
|
+
returning a text-only generation as success.
|
|
32
|
+
|
|
33
|
+
**How to tell which UI your account has:** in the Flow web editor, click
|
|
34
|
+
**Add Media** — a small dialog means the old (working) UI; a navigation to a
|
|
35
|
+
full-page library means the affected new UI.
|
|
36
|
+
|
|
37
|
+
**Note:** the experiment appears to flap — the affected account observed on
|
|
38
|
+
2026-06-12 00:13 was back on the old dialog UI by 12:48 the same day (variant
|
|
39
|
+
probe, issue #174). If you hit exit 7 on entity attach, re-running later the
|
|
40
|
+
same day may simply work again.
|
|
41
|
+
|
|
42
|
+
**Workaround:** none yet on affected accounts — the attach gesture for the new
|
|
43
|
+
UI is being reverse-engineered (recon plan in
|
|
44
|
+
[docs/superpowers/plans/2026-06-12-issue-174-library-ui-attach/PLAN.md](docs/superpowers/plans/2026-06-12-issue-174-library-ui-attach/PLAN.md)).
|
|
45
|
+
If you have a second profile/account still on the old UI, entity attach works
|
|
46
|
+
there. Follow [#174](https://github.com/ffroliva/gflow-cli/issues/174) for
|
|
47
|
+
status; please report whether your account shows the dialog or the full-page
|
|
48
|
+
library (plus your locale) on that issue.
|
|
49
|
+
|
|
50
|
+
### 4K image upscale requires a Flow Ultra subscription
|
|
51
|
+
|
|
52
|
+
- **Status:** **Open** (by design — a Flow platform limit, not a gflow bug)
|
|
53
|
+
- **Severity:** Low · **Affects:** `gflow image upscale --scale 4k` on non-Ultra accounts
|
|
54
|
+
|
|
55
|
+
`gflow image upscale <mediaId> --scale 4k` returns **exit code 22**
|
|
56
|
+
(`UpscaleUnavailableError`) on accounts below the Ultra tier — Flow gates 4K
|
|
57
|
+
upscaling behind Ultra (the web UI shows an "Upgrade" button instead of a 4K
|
|
58
|
+
option). The account tier is reported on the wire as `userPaygateTier` but is
|
|
59
|
+
enforced server-side, so gflow cannot grant 4K locally.
|
|
60
|
+
|
|
61
|
+
**Workaround:** use `--scale 2k` (available on all tiers), or upgrade the Flow
|
|
62
|
+
account to Ultra. If you just upgraded, re-run `gflow auth login --profile <name>`
|
|
63
|
+
to refresh the session before retrying 4K. Wire detail:
|
|
64
|
+
[docs/IMAGE_UPSCALE_RECON.md](docs/IMAGE_UPSCALE_RECON.md) (#171).
|
|
65
|
+
|
|
17
66
|
### Image generation returns HTTP 401 — `aisandbox-pa` generation endpoint
|
|
18
67
|
|
|
19
68
|
- **Status:** **RESOLVED in v0.7.0** — moved to [Resolved](#resolved) section
|
|
@@ -332,7 +381,7 @@ issue and not blocked by any code change in this repo.
|
|
|
332
381
|
|
|
333
382
|
### `UiAutomationTransport` selectors locale-agnostic — issue #24 Phase 5 complete
|
|
334
383
|
|
|
335
|
-
- **Status:** Resolved (pending owner live e2e on non-EN profile) · **Severity:** Low · **Tracking:** [issue #24](https://github.com/ffroliva/gflow-cli/issues/24), [issue #94](https://github.com/ffroliva/gflow-cli/issues/94)
|
|
384
|
+
- **Status:** Resolved (pending owner live e2e on non-EN profile) · **Severity:** Low · **Tracking:** [issue #24](https://github.com/ffroliva/gflow-cli/issues/24), [issue #94](https://github.com/ffroliva/gflow-cli/issues/94), [issue #170](https://github.com/ffroliva/gflow-cli/issues/170)
|
|
336
385
|
|
|
337
386
|
`--lang=en-US` removed in PR #127 (2026-05-30). All selector groups now use
|
|
338
387
|
locale-stable anchors: `IMAGE_MODEL_OPTION_SELECTORS` and
|
|
@@ -343,6 +392,20 @@ issue and not blocked by any code change in this repo.
|
|
|
343
392
|
Playwright kwarg (persists across all in-session navigations). Full resolution
|
|
344
393
|
gate: live e2e with `gflow image t2i` (each model) on a non-EN Chrome profile.
|
|
345
394
|
|
|
395
|
+
**2026-06-12 correction (issue #170):** the "all selector groups" claim above
|
|
396
|
+
had two stragglers — `PICKER_INCLUDE_BUTTON` and `PICKER_CONTEXT_INCLUDE`
|
|
397
|
+
hardcoded the pt-BR caption "Incluir no comando", breaking
|
|
398
|
+
`--reference-entity` (image t2i), movie R2V entity attach, and Vozes voice
|
|
399
|
+
attach on every non-Portuguese account (Flow renders in the ACCOUNT language;
|
|
400
|
+
`?hl=en` cannot override it). Fixed by converting both constants to sequential
|
|
401
|
+
tier cascades — context-menu Tier 1 is the locale-free `add`-ligature menuitem
|
|
402
|
+
scoped to the open menu; the Vozes button has no ligature, so pt/ru/en text
|
|
403
|
+
leads with a lone-iconless-dialog-button structural fallback. The matched tier
|
|
404
|
+
is emitted as `ui_automation_video.include_selector_tier` (drift telemetry),
|
|
405
|
+
exhaustion raises typed `TransportTimeoutError` (exit 9) with a locale-neutral
|
|
406
|
+
remediation hint, and an image-side submit backstop now raises
|
|
407
|
+
`WireFormatError` when a requested entity never rode the wire.
|
|
408
|
+
|
|
346
409
|
**Phase 2 progress (2026-05-25, develop / post-v0.8.1, unreleased):**
|
|
347
410
|
|
|
348
411
|
- **`ONBOARDING_SELECTORS` restructured** — replaced the original 9 English/PT-BR
|
|
@@ -565,6 +628,15 @@ success. The expected authenticated response shape is pinned by the
|
|
|
565
628
|
change surfaces there as a failing test. Start any investigation of a sudden
|
|
566
629
|
`gflow auth login` verification failure at that fixture and `verification.py`.
|
|
567
630
|
|
|
631
|
+
Since PR #168 the production entry point is `verify_flow_profile`, which reads
|
|
632
|
+
the session cookie **directly from Chrome's SQLite store** via `browser_cookie3`
|
|
633
|
+
(a no-browser fast path) and only falls back to launching Playwright when that
|
|
634
|
+
decryption fails. This adds two more local surfaces to check when verification
|
|
635
|
+
fails unexpectedly: a Windows **DPAPI decrypt failure** (cross-user / cross-machine
|
|
636
|
+
key — surfaces as a `RuntimeError` that `auth/cookies.py` normalizes to
|
|
637
|
+
`PermissionError` to trigger the Playwright fallback) and a **locked cookie DB**
|
|
638
|
+
(Chrome still running holds an exclusive SQLite lock). Both degrade fail-closed.
|
|
639
|
+
|
|
568
640
|
---
|
|
569
641
|
|
|
570
642
|
## Resolved
|
|
@@ -590,8 +662,8 @@ Profiles created before this fix continue to work and display `unknown` in the
|
|
|
590
662
|
account column. Re-running `gflow auth login` against an existing profile backfills
|
|
591
663
|
the `.gflow_account` file.
|
|
592
664
|
|
|
593
|
-
See [AUTHENTICATION.md § Profile naming](AUTHENTICATION.md#profile-naming) for the
|
|
594
|
-
new naming convention and [AUTHENTICATION.md § gflow auth list](AUTHENTICATION.md#gflow-auth-list)
|
|
665
|
+
See [AUTHENTICATION.md § Profile naming](docs/AUTHENTICATION.md#profile-naming) for the
|
|
666
|
+
new naming convention and [AUTHENTICATION.md § gflow auth list](docs/AUTHENTICATION.md#gflow-auth-list)
|
|
595
667
|
for the updated `--json` schema.
|
|
596
668
|
|
|
597
669
|
---
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: gflow-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.17.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
|
|
@@ -37,6 +37,7 @@ Classifier: Programming Language :: Python :: 3.12
|
|
|
37
37
|
Classifier: Programming Language :: Python :: 3.13
|
|
38
38
|
Classifier: Topic :: Multimedia :: Video
|
|
39
39
|
Requires-Python: >=3.11
|
|
40
|
+
Requires-Dist: browser-cookie3>=0.20.1
|
|
40
41
|
Requires-Dist: click>=8.1.0
|
|
41
42
|
Requires-Dist: httpx>=0.27.0
|
|
42
43
|
Requires-Dist: platformdirs>=4.0.0
|
|
@@ -68,28 +68,43 @@ python -m pip install --pre gflow-cli
|
|
|
68
68
|
uv run pyright src
|
|
69
69
|
uv run python -m pytest -q --cov=gflow_cli
|
|
70
70
|
```
|
|
71
|
-
4.
|
|
71
|
+
4. **Live-verify the release's user-facing features and record the evidence.**
|
|
72
|
+
**Required gate — do not skip.** Exercise each new/changed user-facing feature
|
|
73
|
+
against live Flow (credit-free wherever possible — image gen, entity attach,
|
|
74
|
+
upscale, and scene/timeline ops cost no Veo credits) and write the result to
|
|
75
|
+
`docs/LIVE_VERIFICATION_vX.Y.Z.md` using the 5-layer ledger (file count + magic
|
|
76
|
+
bytes + dimensions/shape + structlog invariants + user-confirmable artifact).
|
|
77
|
+
Then add it to the "what was live-verified" entry in `docs/INDEX.md`. Every
|
|
78
|
+
release v0.7.0→v0.13.0 had this doc; it lapsed for v0.14.0–v0.15.1 — that gap is
|
|
79
|
+
the reason this is now an explicit step. If a feature genuinely cannot be live-
|
|
80
|
+
verified this cycle, say so in the doc with the reason; never silently omit it.
|
|
81
|
+
5. **Consolidate shipped planning artifacts.** Extract any durable patterns into
|
|
82
|
+
auto-memory, then remove the now-shipped `docs/superpowers/` plan / spec /
|
|
83
|
+
verification files (keep only in-flight work). Stale review docs and session
|
|
84
|
+
markers do not belong in the repo root. (Enforced by `check_repo_hygiene.py` —
|
|
85
|
+
see the root-doc allowlist.)
|
|
86
|
+
6. Update the version in:
|
|
72
87
|
- `pyproject.toml`
|
|
73
88
|
- `src/gflow_cli/__init__.py`
|
|
74
89
|
- any tests that assert the package version
|
|
75
|
-
|
|
90
|
+
7. Move user-visible changes from `CHANGELOG.md` `[Unreleased]` into a dated
|
|
76
91
|
release section.
|
|
77
|
-
|
|
92
|
+
8. Commit the release prep:
|
|
78
93
|
```bash
|
|
79
|
-
git add pyproject.toml src/gflow_cli/__init__.py CHANGELOG.md tests
|
|
94
|
+
git add pyproject.toml src/gflow_cli/__init__.py CHANGELOG.md tests docs
|
|
80
95
|
git commit -m "chore(release): vX.Y.Z"
|
|
81
96
|
```
|
|
82
|
-
|
|
97
|
+
9. Tag and push. **Must be a signed annotated tag** (`-s`) — `.github/workflows/release.yml` rejects unsigned or lightweight tags. Requires a GPG or SSH signing key registered with your GitHub account.
|
|
83
98
|
```bash
|
|
84
99
|
git tag -s vX.Y.Z -m "vX.Y.Z"
|
|
85
100
|
git push origin main
|
|
86
101
|
git push origin vX.Y.Z
|
|
87
102
|
```
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
103
|
+
10. Watch the release workflow:
|
|
104
|
+
<https://github.com/ffroliva/gflow-cli/actions/workflows/release.yml>
|
|
105
|
+
11. Confirm the new version appears on:
|
|
106
|
+
- <https://pypi.org/project/gflow-cli/>
|
|
107
|
+
- <https://github.com/ffroliva/gflow-cli/releases>
|
|
93
108
|
|
|
94
109
|
## Known Historical Quirk
|
|
95
110
|
|
|
@@ -364,6 +364,27 @@ Run: gflow auth login --profile default
|
|
|
364
364
|
|
|
365
365
|
Re-running `auth login` refreshes the cookies in place — no other state is lost.
|
|
366
366
|
|
|
367
|
+
## Session verification (cookie-store fast path)
|
|
368
|
+
|
|
369
|
+
Since v0.17.0, profile verification (run by `gflow auth login --browser chrome` after
|
|
370
|
+
capture) is handled by `gflow_cli.auth.verification.verify_flow_profile`, which probes
|
|
371
|
+
Flow's `/fx/api/auth/session` endpoint **directly from the Chrome cookie store** via
|
|
372
|
+
`browser_cookie3` + `httpx` — no browser launch needed (contributed in PR #168 by
|
|
373
|
+
@3mora2). Two hardening behaviors:
|
|
374
|
+
|
|
375
|
+
- **Encrypted/locked store fallback** — if the cookie store can't be read (e.g.
|
|
376
|
+
Windows DPAPI decryption fails, or the store is locked by a running Chrome), the
|
|
377
|
+
verifier falls back to a marker-gated Playwright probe. The chrome marker is written
|
|
378
|
+
before verification so the fallback can find the profile; on failure only a
|
|
379
|
+
*speculative* marker write is rolled back — a previously-verified profile survives a
|
|
380
|
+
transient probe failure.
|
|
381
|
+
- **Transient-error retry** — HTTP 429/503/504 and network errors retry with
|
|
382
|
+
exponential backoff before the verifier gives up.
|
|
383
|
+
|
|
384
|
+
The outcome is the same `AUTHENTICATED` / no-session decision documented under
|
|
385
|
+
[`gflow auth status`](#gflow-auth-status); only the transport is faster. Cookie
|
|
386
|
+
extraction lives in `gflow_cli.auth.cookies`.
|
|
387
|
+
|
|
367
388
|
## Threat model & limits
|
|
368
389
|
|
|
369
390
|
| Threat | Mitigation |
|
|
@@ -375,7 +375,8 @@ convenience later.
|
|
|
375
375
|
generate) so Flow's JS sets `entityContext` and passes the WAF; gflow captures `media[]`/`workflows[]`
|
|
376
376
|
from the response. Reuse gflow's prompt-submit + response-capture machinery (`ui_automation.py`), but in
|
|
377
377
|
the character-editor context (NOT the new-project flow). Video `--character` reuse = resource picker
|
|
378
|
-
(
|
|
378
|
+
(search resources → Personagens → *include-in-prompt* context-menu action; captions are localized,
|
|
379
|
+
selectors locale-free since issue #170) → generate; mirrors #123 `_attach_likeness`.
|
|
379
380
|
All selectors **ligature/structural only** (language-agnostic).
|
|
380
381
|
- **Cost reality:** the feature is UI-automation-heavy (new character-editor + picker selectors), not the
|
|
381
382
|
"mostly REST" earlier framing. Structural metadata is REST; the value-generating steps are UI.
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# Image Upscale — Reverse-Engineering Recon
|
|
2
|
+
|
|
3
|
+
> Status: **recon complete, pre-implementation**. Wire empirically captured 2026-06-11
|
|
4
|
+
> (denon82 Pro account, project `ffb768fb…`). Spikes: `scripts/dev/spike_image_upscale_drive.py`
|
|
5
|
+
> (UI drive + capture) and `scripts/dev/spike_image_upscale_rest_probe.py` (schema + REST probe).
|
|
6
|
+
|
|
7
|
+
## Feature
|
|
8
|
+
|
|
9
|
+
Flow's image editor download menu offers **1K Original / 2K Upscaled / 4K Upscaled**. gflow
|
|
10
|
+
today saves only the 1K original (the pre-signed `fifeUrl` from the generation response). This
|
|
11
|
+
feature adds `gflow image upscale <mediaId> --scale 2k|4k` to fetch the upscaled variant.
|
|
12
|
+
|
|
13
|
+
Scope: **platform-generated images only** (referenced by `mediaId`). Uploaded images are not
|
|
14
|
+
supported by this endpoint. **4K is Ultra-tier-gated**; Pro accounts see "Upgrade" in the UI.
|
|
15
|
+
|
|
16
|
+
## Wire protocol
|
|
17
|
+
|
|
18
|
+
### Endpoint
|
|
19
|
+
```
|
|
20
|
+
POST https://aisandbox-pa.googleapis.com/v1/flow/upsampleImage
|
|
21
|
+
```
|
|
22
|
+
Same host + auth class as image generation (`batchGenerateImages`).
|
|
23
|
+
|
|
24
|
+
### Request body
|
|
25
|
+
```json
|
|
26
|
+
{
|
|
27
|
+
"mediaId": "<source-image-uuid>",
|
|
28
|
+
"targetResolution": "UPSAMPLE_IMAGE_RESOLUTION_2K",
|
|
29
|
+
"clientContext": {
|
|
30
|
+
"recaptchaContext": {
|
|
31
|
+
"token": "<reCAPTCHA-Enterprise-token>",
|
|
32
|
+
"applicationType": "RECAPTCHA_APPLICATION_TYPE_WEB"
|
|
33
|
+
},
|
|
34
|
+
"projectId": "<project-that-owns-the-media>",
|
|
35
|
+
"sessionId": ";<epoch_ms>",
|
|
36
|
+
"tool": "PINHOLE",
|
|
37
|
+
"userPaygateTier": "PAYGATE_TIER_ONE"
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
- `targetResolution` enum: `UPSAMPLE_IMAGE_RESOLUTION_2K` | `UPSAMPLE_IMAGE_RESOLUTION_4K`.
|
|
42
|
+
1K = original (no API call — gflow already has it).
|
|
43
|
+
- **The FULL `clientContext` is required.** A minimal `{recaptchaContext}` body returns
|
|
44
|
+
**403 even with a valid token** (confirmed by live smoke). All five fields are needed;
|
|
45
|
+
`projectId` (the project owning the media) is load-bearing.
|
|
46
|
+
- `sessionId` format is `;<epoch_ms>` (e.g. `;1781190457842`), same as image generation.
|
|
47
|
+
- `userPaygateTier` is **where the account tier surfaces on the wire** (`PAYGATE_TIER_ONE`
|
|
48
|
+
on a Pro account). It is client-reported telemetry — the server enforces the real tier
|
|
49
|
+
independently (a non-Ultra 4K request 403s regardless), so it is not a security control.
|
|
50
|
+
|
|
51
|
+
### reCAPTCHA action — `IMAGE_GENERATION`
|
|
52
|
+
The token MUST be minted with action **`IMAGE_GENERATION`** (uppercase). reCAPTCHA Enterprise
|
|
53
|
+
scores by action; the guessed `"upsampleImage"` scored low and 403'd. Captured live by hooking
|
|
54
|
+
`grecaptcha.enterprise.execute` (`scripts/dev/spike_image_upscale_recaptcha_action.py`). The
|
|
55
|
+
site key is page-discovered, so it auto-matches; minting on the bootstrap page is fine — the
|
|
56
|
+
action was the only gap. **Live-verified 2026-06-11**: a 2K upscale wrote a 3.8 MB JPEG.
|
|
57
|
+
|
|
58
|
+
### Response
|
|
59
|
+
```json
|
|
60
|
+
{ "encodedImage": "<base64>" }
|
|
61
|
+
```
|
|
62
|
+
- Single field. ~3.8–5.1 MB base64 observed (varies by source image). Decode → write image bytes.
|
|
63
|
+
- Synchronous: one call returns the result. **No async poll/status loop** (unlike video gen).
|
|
64
|
+
|
|
65
|
+
## Transport decision — browser required, REST is dead
|
|
66
|
+
|
|
67
|
+
| Approach | Viable? | Evidence |
|
|
68
|
+
|---|---|---|
|
|
69
|
+
| Pure REST / Bearer-only | ❌ No | Bearer `ya29` + **no** reCAPTCHA token → **403** (probed with and without `clientContext`) |
|
|
70
|
+
| Browser reCAPTCHA-mint + POST | ✅ Yes | UI drive returns 200; reuses the existing `batchGenerateImages` transport |
|
|
71
|
+
| Hybrid (browser submit + Bearer poll) | ⚠️ N/A | No poll/download phase exists — response is synchronous inline base64 |
|
|
72
|
+
|
|
73
|
+
**Conclusion:** reCAPTCHA token is **mandatory**. Reuse the existing image-generation reCAPTCHA
|
|
74
|
+
minting path; there is no Bearer-only slice to peel off. See [REST-path capability matrix] — a
|
|
75
|
+
generative-class op stays reCAPTCHA-gated.
|
|
76
|
+
|
|
77
|
+
## Tier gating (4K = Ultra)
|
|
78
|
+
|
|
79
|
+
- 4K is Ultra-only. On Pro, the UI renders "Fazer upgrade" (Upgrade) instead of a clickable 4K.
|
|
80
|
+
- Account tier is **NOT** in `GET /fx/api/auth/session` (only `user` / `expires` / `access_token`).
|
|
81
|
+
It surfaces via the upsell recommendations (`fetchUserRecommendations` onramp list) and is
|
|
82
|
+
enforced server-side. A 4K request on a non-Ultra account is expected to 403 (permission), which
|
|
83
|
+
must be distinguished from a WAF/reCAPTCHA 403.
|
|
84
|
+
- Session staleness is real: an idle session returns `error: ACCESS_TOKEN_REFRESH_NEEDED` and
|
|
85
|
+
re-auths before the call succeeds — so a freshly-upgraded account may need a session refresh
|
|
86
|
+
before 4K unlocks.
|
|
87
|
+
|
|
88
|
+
## UI navigation facts (for the spike/transport)
|
|
89
|
+
|
|
90
|
+
- **Cold-loading `/project/<pid>/edit/<mediaId>` 500s** ("Algo deu errado"). Must land on the
|
|
91
|
+
gallery `/project/<pid>` then click the `a[href*=<mediaId>]` tile (in-app SPA routing).
|
|
92
|
+
- A "What's new" changelog modal overlays the gallery but does **not** block the href tile click.
|
|
93
|
+
- Working selectors (locale leaks into the UI — match language-neutral tokens):
|
|
94
|
+
- Download button: `button:has(i.google-symbols:text-is('download'))`
|
|
95
|
+
- Scale menu item: `[role='menuitem']:has-text('2K')` (and `'4K'`)
|
|
96
|
+
- pt labels are 1K="Tamanho original", 2K/4K="Aumentada" — **never** match on "Aumentada".
|
|
97
|
+
|
|
98
|
+
## Implementation sketch (from `/gflow:predict` GO, 7.5/10)
|
|
99
|
+
|
|
100
|
+
- `api/routes.py`: `UPSAMPLE_IMAGE = f"{FLOW_API_BASE}/flow/upsampleImage"`.
|
|
101
|
+
- `api/image.py`: frozen `UpsampleImageRequest(media_id, target_resolution, recaptcha_token="")`;
|
|
102
|
+
`TargetResolution` enum with `from_cli("2k"|"4k")`.
|
|
103
|
+
- `api/client.py`: `upsample_image()` — mint reCAPTCHA (existing path), POST, validate + decode
|
|
104
|
+
`encodedImage` with `MAX_UPSAMPLE_B64_LEN ≈ 50 MB` cap + `del` + PNG/JPEG magic-byte check
|
|
105
|
+
(mirror `concatenate_scene`).
|
|
106
|
+
- `cli_image.py`: `gflow image upscale <mediaId> --scale 2k|4k [--out]`.
|
|
107
|
+
- `errors.py`: `UpscaleUnavailableError` (exit 22), distinct from WAF/reCAPTCHA 403; **no auto-retry**
|
|
108
|
+
on a 4K 403.
|
|
109
|
+
- Never log `encodedImage`. Record the output via `OperationRecorder` honoring the redaction gate.
|
|
110
|
+
- Discover mediaIds via the existing `gflow data list images`.
|
|
111
|
+
|
|
112
|
+
## Credit cost
|
|
113
|
+
|
|
114
|
+
Image operation → expected **credit-free** (only video generation spends credits). Not yet
|
|
115
|
+
stress-confirmed; treat as free but do not batch aggressively (per-profile WAF heat).
|
|
@@ -34,6 +34,7 @@ Welcome to the `gflow-cli` documentation. This index is the routing layer: it te
|
|
|
34
34
|
| **[docs/DATA_LAYER.md](DATA_LAYER.md)** | Local SQLite catalog: goals, schema, recording flow, redaction, `gflow data` CLI, migrations, extension guide | Anything touching `gflow_cli.data`, debugging missing rows, building I2V/repair tooling, auditing what is stored |
|
|
35
35
|
| **[docs/CHARACTER.md](CHARACTER.md)** | Characters feature spec & system design: domain model, endpoint/cost matrix, sequence diagrams, JSON payloads (I/O), CLI surface, reuse via `referenceEntities` (#145) | Working on `gflow character`, reusing a character in generations, or understanding Flow's character wire protocol |
|
|
36
36
|
| **[docs/MOVIE.md](MOVIE.md)** | `gflow movie` — multi-scene character-consistent films: manifest format, run lifecycle (browser stays open through generate→poll→download), entity-attach mechanism (Personagens right-click), resume/handoff, credits | Working on `gflow movie`, debugging scene generation, or understanding the character-entity attach + consistency model |
|
|
37
|
+
| **[docs/IMAGE_UPSCALE_RECON.md](IMAGE_UPSCALE_RECON.md)** | `gflow image upscale` wire protocol: `upsampleImage` endpoint, full clientContext (projectId/sessionId/tool/userPaygateTier), reCAPTCHA action `IMAGE_GENERATION`, inline base64 response, 4K Ultra-gating, REST-is-dead proof | Working on `gflow image upscale`, debugging the 403/reCAPTCHA path, or understanding Flow's image-upscale wire protocol (#171) |
|
|
37
38
|
| **[tasks/lessons.md](../tasks/lessons.md)** | Running notebook of patterns + reviewer findings, dated and traced to commits | Starting a new phase; debugging "why did the council flag this?" |
|
|
38
39
|
| **[skills/README.md](../skills/README.md)** | Installable agent skill docs (gflow-cli, predict, pr-council-review, scenario) — cross-tool portable Markdown consumed by Claude Code, Cursor, Codex, Gemini CLI, Aider, etc. | Any agent wanting to use gflow-cli correctly |
|
|
39
40
|
| **[scripts/dev/skillopt/README.md](../scripts/dev/skillopt/README.md)** | SkillOpt mock harness — rollout→score loop for measuring and improving skill doc accuracy across multiple LLM providers | Measuring a skill edit's impact; comparing Claude vs GPT-4o vs Gemini on gflow tasks |
|
|
@@ -84,6 +85,7 @@ Slash commands for Claude Code, stored in `.claude/commands/gflow/`. All prefixe
|
|
|
84
85
|
**"How do I run with multiple Google accounts?"** → [AUTHENTICATION § Multiple accounts](AUTHENTICATION.md#multiple-accounts)
|
|
85
86
|
**"How do I know which Google account a profile is signed into?"** → [AUTHENTICATION § gflow auth list](AUTHENTICATION.md#gflow-auth-list)
|
|
86
87
|
**"Why is my profile named 'default' and how do I rename it?"** → [AUTHENTICATION § Profile naming](AUTHENTICATION.md#profile-naming)
|
|
88
|
+
**"How does login verification work without launching a browser?"** → [AUTHENTICATION § Session verification](AUTHENTICATION.md#session-verification-cookie-store-fast-path) (cookie-store fast path, v0.17.0)
|
|
87
89
|
**"How does the layered structure work?"** → [ARCHITECTURE § Layers](ARCHITECTURE.md#layers)
|
|
88
90
|
**"What env var should I set for X?"** → [CONFIGURATION § Reference](CONFIGURATION.md#reference)
|
|
89
91
|
**"What does gflow remember after a generation finishes?"** → [DATA_LAYER § What is recorded](DATA_LAYER.md#what-is-recorded)
|
|
@@ -109,7 +111,8 @@ Slash commands for Claude Code, stored in `.claude/commands/gflow/`. All prefixe
|
|
|
109
111
|
**"A gflow command hangs / fails — where do I start?"** → [DEBUGGING § Quick reference](DEBUGGING.md#quick-reference)
|
|
110
112
|
**"Flow's UI broke a selector — how do I diagnose it?"** → [DEBUGGING § Inspecting Flow's live UI](DEBUGGING.md#inspecting-flows-live-ui)
|
|
111
113
|
**"What does each `ui_automation.*` log event mean?"** → [DEBUGGING § Listener & HTTP-layer debugging](DEBUGGING.md#listener--http-layer-debugging)
|
|
112
|
-
**"What was actually live-verified for the latest release?"** → v0.15.0 / v0.
|
|
114
|
+
**"What was actually live-verified for the latest release?"** → latest: [LIVE_VERIFICATION_v0.17.0](LIVE_VERIFICATION_v0.17.0.md) (#168 cookie verification live e2e_auth; #177 exit-7 hint recorded not-triggerable, credit-free). v0.14.0 / v0.15.0 / v0.15.1 shipped without a dedicated doc (CI + the v0.13.0 baseline). Prior: [v0.16.0](LIVE_VERIFICATION_v0.16.0.md) · [v0.13.0](LIVE_VERIFICATION_v0.13.0.md) · [v0.12.0](LIVE_VERIFICATION_v0.12.0.md) · [v0.11.0](LIVE_VERIFICATION_v0.11.0.md) · [v0.10.0](LIVE_VERIFICATION_v0.10.0.md) · [v0.9.1](LIVE_VERIFICATION_v0.9.1.md) · [v0.9.0](LIVE_VERIFICATION_v0.9.0.md) · [v0.8.1](LIVE_VERIFICATION_v0.8.1.md) · [v0.7.0](LIVE_VERIFICATION_v0.7.0.md)
|
|
115
|
+
**"Where is the reverse-engineered wire protocol for a feature?"** → the `*_RECON.md` design docs: [CHARACTER_RECON](CHARACTER_RECON.md) (Flow character entity protocol), [IMAGE_UPSCALE_RECON](IMAGE_UPSCALE_RECON.md) (`/v1/flow/upsampleImage` wire). Naming convention: one `<FEATURE>_RECON.md` per reverse-engineered surface, kept as the durable spec after the feature ships.
|
|
113
116
|
**"What was live-verified for the data layer (PR #58)?"** → [LIVE_VERIFICATION_data_layer](LIVE_VERIFICATION_data_layer.md) — 1 Imagen + 1 Veo credit on denon82, 6-layer ledger (file + magic + Pillow + DB rows + CLI round-trip + structlog)
|
|
114
117
|
**"What was live-verified for the video-download feature (#29)?"** → [LIVE_VERIFICATION_video_download](LIVE_VERIFICATION_video_download.md)
|
|
115
118
|
**"What is the jitter matrix evidence for `gflow image batch`?"** → [`LIVE_VERIFICATION_image_batch.md`](LIVE_VERIFICATION_image_batch.md) — jitter matrix evidence for `gflow image batch` (always-same-project mode)
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# Live verification — v0.16.0
|
|
2
|
+
|
|
3
|
+
> Evidence record for the v0.16.0 release. v0.16.0 ships two features: locale-free
|
|
4
|
+
> resource-picker include selectors (issue #170, PR #173) and `gflow image upscale`
|
|
5
|
+
> (issue #171, PR #172). Backfilled 2026-06-12 to close the live-verification
|
|
6
|
+
> documentation gap that opened after v0.13.0 (see docs/INDEX.md).
|
|
7
|
+
|
|
8
|
+
## Summary
|
|
9
|
+
|
|
10
|
+
- **Verified by:** ffroliva (Claude Code)
|
|
11
|
+
- **Dates:** #171 upscale — 2026-06-11 (feature branch); #170 selectors — 2026-06-12 (released PyPI artifact)
|
|
12
|
+
- **gflow-cli version:** 0.16.0
|
|
13
|
+
- **Status:** 🟢 Green — both features live-verified credit-free; no Veo credits spent
|
|
14
|
+
|
|
15
|
+
All verification below is **credit-free**: image generation, character-entity attach,
|
|
16
|
+
and image upscale are non-Veo operations (see the credits-are-videos-only note in
|
|
17
|
+
`KNOWN_ISSUES.md`). No video generation was exercised for this release.
|
|
18
|
+
|
|
19
|
+
## 1. Quality gates
|
|
20
|
+
|
|
21
|
+
- [x] **Lint/format** — `ruff check` + `ruff format --check` clean (`src` + `tests`).
|
|
22
|
+
- [x] **Type check** — `pyright src`: 0 errors.
|
|
23
|
+
- [x] **Unit + BDD tests** — full suite green in CI across Python 3.11 / 3.12 / 3.13 (PR #173, PR #172).
|
|
24
|
+
- [x] **Repo hygiene + doc links** — `check_repo_hygiene.py` + `check_doc_links.py` green.
|
|
25
|
+
|
|
26
|
+
## 2. Issue #170 — locale-free picker include selectors (PR #173)
|
|
27
|
+
|
|
28
|
+
The pt-BR-hardcoded resource-picker include selectors broke entity attach on every
|
|
29
|
+
non-Portuguese account. PR #173 replaced them with sequentially-probed tier cascades
|
|
30
|
+
(locale-invariant ligature anchor first, then localized-text fallback) and added an
|
|
31
|
+
image-side submit backstop that fails loudly (`WireFormatError`, exit 7) if a staged
|
|
32
|
+
entity never reaches the wire.
|
|
33
|
+
|
|
34
|
+
### E2E evidence (live Flow, credit-free)
|
|
35
|
+
|
|
36
|
+
| Layer | Criterion | Outcome |
|
|
37
|
+
|---|---|---|
|
|
38
|
+
| Selector tier | `include_selector_tier=icon` logged (locale-free anchor matched) | **PASS** |
|
|
39
|
+
| Attach event | `ui_automation.character_entity_attached` fired | **PASS** |
|
|
40
|
+
| Submit backstop | `ui_automation.image_entities_attached` — entity rode the wire | **PASS** |
|
|
41
|
+
| Output artifact | t2i produced a JPEG, **768×1376**, character identity visibly preserved | **PASS** |
|
|
42
|
+
| Version | all events emitted at `cli_version 0.16.0` | **PASS** |
|
|
43
|
+
|
|
44
|
+
- **Pre-merge:** live credit-free `gflow image t2i --reference-entity` on **promo-denon82**
|
|
45
|
+
(pt-BR profile). Recon harness: `scripts/dev/spike_issue170_picker_locale_recon.py`.
|
|
46
|
+
- **Released-artifact re-verification (2026-06-12):** installed `gflow-cli==0.16.0` from
|
|
47
|
+
PyPI (global `uv tool`) and re-ran the same flow on promo-denon82 — all four layers
|
|
48
|
+
above green at `cli_version 0.16.0`. **5-layer ledger PASS.**
|
|
49
|
+
- The backstop earned its keep immediately: it converted Flow's new full-page library-UI
|
|
50
|
+
A/B (issue #174) from a silent text-only "success" into a typed exit-7 failure on its
|
|
51
|
+
first live encounter.
|
|
52
|
+
|
|
53
|
+
## 3. Issue #171 — `gflow image upscale` (PR #172)
|
|
54
|
+
|
|
55
|
+
`gflow image upscale <mediaId> --scale 2k|4k` upscales a platform-generated image via
|
|
56
|
+
Flow's `POST /v1/flow/upsampleImage` (reCAPTCHA-gated, inline base64 response). 4K is
|
|
57
|
+
Ultra-gated and fails fast with `UpscaleUnavailableError` (exit 22) on lower tiers.
|
|
58
|
+
|
|
59
|
+
### E2E evidence (live Flow, credit-free)
|
|
60
|
+
|
|
61
|
+
| Layer | Criterion | Outcome |
|
|
62
|
+
|---|---|---|
|
|
63
|
+
| Wire | `POST /v1/flow/upsampleImage` accepted (full 5-field `clientContext`, action `IMAGE_GENERATION`) | **PASS** |
|
|
64
|
+
| File written | local JPEG written, **3,799,245 bytes** | **PASS** |
|
|
65
|
+
| Magic bytes | header `FF D8 FF` (valid JPEG) | **PASS** |
|
|
66
|
+
| Byte fidelity | written bytes matched the decoded wire payload | **PASS** |
|
|
67
|
+
| Tier gate | 4K returns exit 22 (`UpscaleUnavailableError`) on non-Ultra, not a generic 403 | **PASS** |
|
|
68
|
+
|
|
69
|
+
- Verified 2026-06-11 on the `feature/image-upscale` branch (= the code released as
|
|
70
|
+
v0.16.0): `gflow image upscale <mediaId> --scale 2k --project <pid>` end-to-end.
|
|
71
|
+
- Wire protocol documented in [`docs/IMAGE_UPSCALE_RECON.md`](IMAGE_UPSCALE_RECON.md).
|
|
72
|
+
|
|
73
|
+
## 4. Documentation
|
|
74
|
+
|
|
75
|
+
- `CHANGELOG.md` — v0.16.0 entry covers both features.
|
|
76
|
+
- `KNOWN_ISSUES.md` — 4K-Ultra limit documented; library-UI A/B (#174) tracked.
|
|
77
|
+
- `docs/IMAGE_UPSCALE_RECON.md` — reverse-engineered upscale wire.
|