gflow-cli 0.33.0__tar.gz → 0.34.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.33.0 → gflow_cli-0.34.0}/.env.template +12 -3
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/AGENTS.md +1 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/CHANGELOG.md +12 -1
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/CONTRIBUTING.md +13 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/PKG-INFO +1 -1
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/docs/CONFIGURATION.md +19 -6
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/docs/INDEX.md +1 -1
- gflow_cli-0.34.0/docs/LIVE_VERIFICATION_v0.34.0.md +49 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/docs/USAGE.md +6 -0
- gflow_cli-0.34.0/docs/superpowers/spikes/2026-07-12-ui-cohort-backend-config.md +87 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/pyproject.toml +1 -1
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/skills/pr-council-review/SKILL.md +15 -3
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/__init__.py +1 -1
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/api/image.py +4 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/api/transports/drivers/factory.py +38 -9
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/api/transports/ui_automation.py +24 -52
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/cli_image.py +36 -1
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/config.py +92 -5
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/errors.py +42 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/mcp/tools.py +15 -1
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/worker/daemon.py +2 -1
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/api/transports/drivers/test_factory.py +4 -36
- gflow_cli-0.34.0/tests/api/transports/drivers/test_ui_mode.py +276 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/api/transports/test_ui_automation.py +41 -46
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/api/transports/test_ui_automation_batch.py +5 -4
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/uv.lock +1 -1
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/.claude/README.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/.claude/commands/gflow/active.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/.claude/commands/gflow/branch-review.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/.claude/commands/gflow/changelog.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/.claude/commands/gflow/check.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/.claude/commands/gflow/doc-review.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/.claude/commands/gflow/issue-assessment.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/.claude/commands/gflow/issue-resolve.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/.claude/commands/gflow/known-issues.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/.claude/commands/gflow/next.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/.claude/commands/gflow/plan.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/.claude/commands/gflow/pr-council-review.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/.claude/commands/gflow/predict.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/.claude/commands/gflow/release.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/.claude/commands/gflow/scenario.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/.claude/commands/gflow/sonar.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/.claude/commands/gflow/status.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/.gitattributes +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/.github/CODEOWNERS +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/.github/copilot-instructions.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/.github/dependabot.yml +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/.github/workflows/ci.yml +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/.github/workflows/external-pr-triage.yml +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/.github/workflows/governance-advisory.yml +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/.github/workflows/governance-benchmark.yml +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/.github/workflows/main-base-guard.yml +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/.github/workflows/release.yml +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/.gitignore +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/.gitleaks.toml +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/.pre-commit-config.yaml +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/.secrets.baseline +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/CLAUDE.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/CONFIGURATION.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/DISCLAIMER.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/GEMINI.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/KNOWN_ISSUES.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/LICENSE +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/PLAN.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/README.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/RELEASE.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/ROADMAP.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/conftest.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/docker-compose.yml +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/docs/AGENT_GUIDE.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/docs/AGENT_UI_E2E.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/docs/AGENT_UI_RECON.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/docs/ARCHITECTURE.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/docs/AUTHENTICATION.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/docs/CHARACTER.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/docs/CHARACTER_RECON.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/docs/DATA_LAYER.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/docs/DEBUGGING.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/docs/DEMOS.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/docs/DEVELOPMENT.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/docs/E2E_TESTING.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/docs/EXTERNAL_STORAGE.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/docs/GITHUB.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/docs/GOVERNANCE_BENCHMARK.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/docs/IMAGE_UPSCALE_RECON.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/docs/INSTRUCTIONS.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/docs/LIVE_VERIFICATION_data_layer.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/docs/LIVE_VERIFICATION_image_batch.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/docs/LIVE_VERIFICATION_v0.10.0.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/docs/LIVE_VERIFICATION_v0.11.0.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/docs/LIVE_VERIFICATION_v0.12.0.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/docs/LIVE_VERIFICATION_v0.13.0.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/docs/LIVE_VERIFICATION_v0.16.0.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/docs/LIVE_VERIFICATION_v0.17.0.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/docs/LIVE_VERIFICATION_v0.18.0.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/docs/LIVE_VERIFICATION_v0.19.0.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/docs/LIVE_VERIFICATION_v0.20.0.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/docs/LIVE_VERIFICATION_v0.20.1.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/docs/LIVE_VERIFICATION_v0.21.0.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/docs/LIVE_VERIFICATION_v0.22.0.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/docs/LIVE_VERIFICATION_v0.23.0.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/docs/LIVE_VERIFICATION_v0.24.0.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/docs/LIVE_VERIFICATION_v0.25.0.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/docs/LIVE_VERIFICATION_v0.26.0.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/docs/LIVE_VERIFICATION_v0.27.0.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/docs/LIVE_VERIFICATION_v0.27.1.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/docs/LIVE_VERIFICATION_v0.28.0.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/docs/LIVE_VERIFICATION_v0.29.0.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/docs/LIVE_VERIFICATION_v0.30.0.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/docs/LIVE_VERIFICATION_v0.31.0.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/docs/LIVE_VERIFICATION_v0.32.0.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/docs/LIVE_VERIFICATION_v0.32.1.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/docs/LIVE_VERIFICATION_v0.33.0.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/docs/LIVE_VERIFICATION_v0.7.0.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/docs/LIVE_VERIFICATION_v0.8.1.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/docs/LIVE_VERIFICATION_v0.9.0.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/docs/LIVE_VERIFICATION_v0.9.1.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/docs/LIVE_VERIFICATION_video_download.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/docs/MCP.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/docs/MOVIE.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/docs/PROJECT_STATUS.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/docs/PROMPT_EXPANSION.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/docs/SECURITY.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/docs/TOOLS.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/docs/USER_GUIDE.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/docs/assets/demo-split-pf.gif +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/docs/assets/example-run.gif +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/docs/assets/examples.webp +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/docs/medium_tutorial.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/docs/schemas/movie-handoff.schema.json +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/docs/sonar-cleanup-tracker.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/docs/superpowers/plans/2026-06-12-issue-174-library-ui-attach/PLAN.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/docs/superpowers/plans/2026-06-22-mcp-server/PLAN.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/docs/superpowers/plans/2026-06-22-mcp-server/PREDICT.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/docs/superpowers/plans/2026-06-22-mcp-server/SCENARIO.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/docs/superpowers/plans/2026-06-22-prompt-expansion/PLAN.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/docs/superpowers/plans/2026-06-22-prompt-expansion/PREDICT.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/docs/superpowers/plans/2026-06-22-prompt-expansion/SCENARIO.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/docs/superpowers/plans/2026-06-24-gflow-studio-scaffold/PLAN.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/docs/superpowers/plans/2026-06-24-rest-api-layer/PLAN.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/docs/superpowers/plans/2026-06-26-mcp-e2e-test/PLAN.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/docs/superpowers/plans/2026-07-09-camoufox-adoption/PLAN.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/docs/superpowers/research/2026-06-27-tool-abstraction-evaluation.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/docs/superpowers/specs/2026-06-29-issue-assessment-workflow-design.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/docs/superpowers/spikes/2026-07-09-camoufox-waf-403.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/examples/README.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/examples/batch_from_config.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/examples/multi_prompt_t2i.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/examples/sample_config.json +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/examples/sample_prompts.txt +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/examples/single_image_t2i.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/examples/workflow_chain.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/llms.txt +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/samples/README.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/samples/captured/01_upload_image.json +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/samples/captured/02_batchAsyncGenerateVideoText.json +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/samples/captured/03_batchCheckAsyncVideoGenerationStatus.json +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/samples/captured/04_archive_workflow.json +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/samples/captured/05_createProject.json +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/samples/captured/06_batchGenerateImages.json +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/samples/captured/07_batchGenerateImages_seeded.json +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/samples/captured/08_batchAsyncGenerateVideoStartAndEndImage.json +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/samples/captured/09_batchAsyncGenerateVideoReferenceImages.json +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/samples/captured/10_batchCheckAsyncVideoGenerationStatus_successful.json +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/samples/captured/11_batchCheckAsyncVideoGenerationStatus_failed.json +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/samples/captured/12_create_scene.json +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/samples/captured/13_sceneWorkflows_update.json +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/samples/captured/14_get_scene_workflows.json +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/samples/captured/15_commit_flowWorkflow.json +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/scripts/ci/check_doc_links.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/scripts/ci/check_materiality.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/scripts/ci/check_repo_hygiene.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/scripts/debug_editor.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/scripts/debug_gen_settings.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/scripts/debug_settings.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/scripts/dev/_recording_client.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/scripts/dev/_spike_common.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/scripts/dev/active_plan.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/scripts/dev/analyze_agent_ui_capture.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/scripts/dev/capture_i2v_frame_slots_dom.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/scripts/dev/capture_i2v_intercept_submit.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/scripts/dev/capture_i2v_model_select_repro.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/scripts/dev/capture_i2v_post_bind_state.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/scripts/dev/capture_image_add_media_dom.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/scripts/dev/capture_locale_invariants.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/scripts/dev/cdp_drive_and_probe.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/scripts/dev/character_create_spike.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/scripts/dev/character_create_spike_v2.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/scripts/dev/dump_character_selectors.js +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/scripts/dev/make_project.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/scripts/dev/materiality_backtest.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/scripts/dev/monitor_pr_38.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/scripts/dev/patch_character.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/scripts/dev/skillopt/README.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/scripts/dev/skillopt/harness.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/scripts/dev/skillopt/tasks.json +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/scripts/dev/spike_char_editor_dom.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/scripts/dev/spike_char_gen_capture.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/scripts/dev/spike_image_upscale_capture.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/scripts/dev/spike_image_upscale_drive.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/scripts/dev/spike_image_upscale_recaptcha_action.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/scripts/dev/spike_image_upscale_rest_probe.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/scripts/dev/spike_issue170_picker_locale_recon.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/scripts/dev/spike_issue174_library_ui_recon.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/scripts/dev/spike_movie_attach_payload.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/scripts/dev/spike_movie_entity_recon.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/scripts/dev/spike_movie_gen_capture.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/scripts/dev/spike_movie_picker_select.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/scripts/dev/spike_movie_voice_list.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/scripts/dev/spike_patch_entity.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/scripts/dev/spike_patchright.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/scripts/diag/README.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/scripts/diag/capture_flow_traffic.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/scripts/diag/memory_profile.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/scripts/diag/recaptcha_mint.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/scripts/e2e/agentic_image_e2e.ps1 +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/scripts/e2e/capture_agent_toggle.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/scripts/record_demo.ps1 +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/scripts/smoke_image.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/scripts/smoke_real_chrome_image.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/scripts/smoke_video_editor.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/scripts/smoke_worker_style.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/scripts/spike_waf_camoufox.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/scripts/verify_chrome_auth_viability.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/skills/README.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/skills/gflow-cli/SKILL.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/skills/issue-assessment/SKILL.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/skills/issue-resolve/SKILL.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/skills/plan/SKILL.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/skills/predict/SKILL.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/skills/scenario/SKILL.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/skills/status/SKILL.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/sonar-project.properties +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/__main__.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/_cli_helpers.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/api/__init__.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/api/_engine.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/api/_retry.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/api/_sapisidhash.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/api/character.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/api/client.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/api/dto.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/api/image_upscale.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/api/recaptcha.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/api/routes.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/api/scene.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/api/transports/__init__.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/api/transports/_common.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/api/transports/_fingerprint.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/api/transports/base.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/api/transports/drivers/__init__.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/api/transports/drivers/agentic.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/api/transports/drivers/base.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/api/transports/drivers/classic.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/api/transports/experimental/__init__.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/api/transports/experimental/bearer.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/api/transports/experimental/evaluate_fetch.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/api/transports/experimental/sapisidhash.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/api/transports/ui_automation_video.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/api/video.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/auth/__init__.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/auth/base.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/auth/cookies.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/auth/factory.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/auth/internal_chromium.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/auth/real_chrome.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/auth/strategies.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/auth/verification.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/browser_manager.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/chain.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/chain_manifest.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/cli.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/cli_character.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/cli_data.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/cli_instructions.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/cli_models.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/cli_movie.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/cli_run.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/cli_scene.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/cli_tools.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/cli_video.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/composition.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/data/__init__.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/data/chain_repo.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/data/migrations/0001_initial.sql +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/data/migrations/0002_add_cloud_storage.sql +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/data/migrations/0003_add_scene_tables.sql +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/data/migrations/0004_add_scene_output_path.sql +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/data/migrations/0005_add_chain_links.sql +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/data/migrations/0006_add_operations_metadata.sql +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/data/migrations/0007_queue.sql +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/data/migrations/0008_add_operation_expanded_prompt.sql +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/data/migrations/__init__.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/data/models.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/data/queries.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/data/recorder.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/data/redaction.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/data/repository.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/data/store.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/exceptions.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/image_batch.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/json_output.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/manifest.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/mcp/__init__.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/mcp/prompts.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/mcp/resources.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/mcp/server.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/media.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/movie_manifest.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/observability.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/paths.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/profile_store.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/services/__init__.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/services/character_create.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/storage.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/tools/__init__.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/tools/banned.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/tools/builtin/__init__.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/tools/builtin/creative-director.toml +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/tools/expander.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/tools/invocation.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/tools/loader.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/tools/registry.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/tools/runtime.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/tools/spec.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/ui/app.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/ui/server.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/src/gflow_cli/worker/queue.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tasks/lessons.md +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/test_assets/sample_batch.json +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/test_assets/sample_batch.tsv +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/test_assets/sample_batch_invalid.tsv +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/__init__.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/api/__init__.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/api/fixtures/character_gen_response.json +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/api/fixtures/patch_entity_response.json +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/api/test_aisandbox_auth_error.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/api/test_aisandbox_auth_headers.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/api/test_bearer_redaction.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/api/test_character.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/api/test_client.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/api/test_client_character.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/api/test_client_delete_characters.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/api/test_client_generate_character.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/api/test_client_image.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/api/test_client_launch_kwargs.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/api/test_client_patch_entity.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/api/test_client_scene.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/api/test_client_upscale.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/api/test_concurrency.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/api/test_dto.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/api/test_engine.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/api/test_image.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/api/test_image_dto.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/api/test_image_upscale.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/api/test_post_json_aisandbox_auth.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/api/test_recaptcha.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/api/test_retry.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/api/test_routes.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/api/test_routes_character.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/api/test_routes_scene.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/api/test_sapisidhash_helper.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/api/test_scene_models.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/api/test_video.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/api/test_video_request.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/api/transports/__init__.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/api/transports/conftest.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/api/transports/drivers/__init__.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/api/transports/drivers/test_agentic.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/api/transports/drivers/test_classic.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/api/transports/test_base.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/api/transports/test_bearer.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/api/transports/test_common.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/api/transports/test_evaluate_fetch.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/api/transports/test_factory.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/api/transports/test_fingerprint.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/api/transports/test_sapisidhash.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/api/transports/test_selector_symmetry.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/api/transports/test_transport_timeout.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/api/transports/test_ui_automation_image_mode.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/api/transports/test_ui_automation_video.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/api/transports/test_ui_character_editor.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/auth/strategies/test_factory.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/auth/strategies/test_strategies.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/auth/test_cookies.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/auth/test_verification.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/cli/__init__.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/cli/test_cli_auth_list.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/cli/test_cli_character.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/cli/test_cli_character_create.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/cli/test_cli_data.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/cli/test_cli_image.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/cli/test_cli_image_seed_removed.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/cli/test_cli_image_selector_drift.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/cli/test_cli_image_upscale.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/cli/test_cli_instructions.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/cli/test_cli_models.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/cli/test_cli_movie.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/cli/test_cli_run.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/cli/test_cli_scene.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/cli/test_cli_tools.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/cli/test_cli_video.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/cli/test_cli_video_chain.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/cli/test_error_handling.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/cli/test_helpers.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/cli/test_movie_manifest.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/cli/test_movie_manifest_style_variants.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/cli/test_settings_validation.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/cli/test_t2i_multi_prompt.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/composition/test_character.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/composition/test_compose_prompt.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/composition/test_handoff.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/composition/test_style_variants.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/composition/test_style_variants_e2e.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/conftest.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/data/__init__.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/data/test_chain_repo.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/data/test_find_incomplete_character.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/data/test_models.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/data/test_packaging.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/data/test_recorder.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/data/test_recorder_character.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/data/test_redaction.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/data/test_repository.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/data/test_scene_persistence.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/data/test_settings_and_errors.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/data/test_store_migrations.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/dev/test_recording_client.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/e2e/__init__.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/e2e/conftest.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/e2e/test_aisandbox_auth_live.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/e2e/test_auth_verification_e2e.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/e2e/test_chain_e2e.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/e2e/test_character_create_e2e.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/e2e/test_daemon_e2e.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/e2e/test_data_layer_e2e.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/e2e/test_i2v_flags_e2e.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/e2e/test_image_batch_e2e.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/e2e/test_image_i2i_ref_cap_e2e.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/e2e/test_json_output_e2e.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/e2e/test_live_agentic_instructions.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/e2e/test_locale_selectors_e2e.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/e2e/test_scene_compose_live.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/e2e/test_tools_e2e.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/e2e/test_transports_e2e.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/e2e/test_video_r2v_ref_cap_e2e.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/e2e/test_video_t2v_e2e.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/features/__init__.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/features/auth.feature +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/features/auth_login.feature +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/features/character_create.feature +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/features/character_read.feature +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/features/conftest.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/features/image.feature +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/features/image_upscale.feature +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/features/instructions.feature +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/features/locale_picker_include.feature +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/features/test_auth_login_steps.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/features/test_auth_steps.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/features/test_character_create_steps.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/features/test_character_read_steps.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/features/test_image_steps.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/features/test_image_upscale_steps.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/features/test_instructions_steps.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/features/test_locale_picker_include_steps.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/features/test_step_collision_guard.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/features/test_video_agent_ui_steps.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/features/test_video_chain_steps.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/features/video_agent_ui.feature +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/features/video_chain.feature +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/fixtures/__init__.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/fixtures/seeded_catalog.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/image_batch/__init__.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/image_batch/test_image_manifest.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/image_batch/test_jitter_config.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/image_batch/test_observability_events.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/integration/__init__.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/integration/conftest.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/integration/constants.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/integration/test_storage_gcs.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/integration/test_storage_s3.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/mcp/__init__.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/mcp/conftest.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/mcp/test_cli_parity.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/mcp/test_server.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/mcp/test_stdio_transport.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/mcp/test_tools_helpers.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/mcp/test_tools_instructions.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/mcp/test_tools_wired.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/scripts/test_analyze_agent_ui_capture.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/scripts/test_capture_locale_invariants.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/scripts/test_check_materiality.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/scripts/test_check_repo_hygiene.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/scripts/test_materiality_backtest.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/services/__init__.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/services/test_character_create_redaction.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/services/test_character_create_saga.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/services/test_character_gen_no_direct_post.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/smoke/__init__.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/smoke/test_profile_account_smoke.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/smoke/test_real_flow.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/test_auth.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/test_browser_manager.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/test_chain.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/test_chain_manifest.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/test_cli_data.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/test_config.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/test_conftest_isolation.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/test_data_queries.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/test_documentation_gate.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/test_errors.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/test_errors_403.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/test_json_output.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/test_manifest.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/test_marker_registry.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/test_media.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/test_observability.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/test_paths.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/test_profile_store.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/test_smoke.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/tools/__init__.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/tools/test_banned.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/tools/test_expander.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/tools/test_invocation.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/tools/test_loader.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/tools/test_registry.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/tools/test_runtime.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/tools/test_spec.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/ui/test_app.py +0 -0
- {gflow_cli-0.33.0 → gflow_cli-0.34.0}/tests/worker/test_daemon.py +0 -0
|
@@ -123,11 +123,20 @@
|
|
|
123
123
|
# `patchright install chromium`. Unset to revert to the default playwright engine.
|
|
124
124
|
# GFLOW_CLI_BROWSER_ENGINE=playwright
|
|
125
125
|
|
|
126
|
-
#
|
|
127
|
-
#
|
|
128
|
-
#
|
|
126
|
+
# Which Flow UI arm a command needs: auto (bind whatever renders) | classic
|
|
127
|
+
# (require the hard aspect controls) | agentic (require the chat surface; needed
|
|
128
|
+
# for -i instructions). gflow switches to the required arm, verifies via re-probe,
|
|
129
|
+
# and aborts with exit 28 (retryable — the cohort flaps per load) if it can't be
|
|
130
|
+
# reached. -i instructions force agentic automatically. See docs/CONFIGURATION.md.
|
|
131
|
+
# GFLOW_CLI_UI_MODE=auto
|
|
132
|
+
|
|
133
|
+
# DEPRECATED — use GFLOW_CLI_UI_MODE=classic. true maps to ui_mode=classic, but the
|
|
134
|
+
# old silent agentic fallback is gone: a classic-required run now aborts (exit 28).
|
|
129
135
|
# GFLOW_CLI_PREFER_CLASSIC=false
|
|
130
136
|
|
|
137
|
+
# DEPRECATED — use GFLOW_CLI_UI_MODE=agentic. true maps to ui_mode=agentic.
|
|
138
|
+
# GFLOW_CLI_FORCE_AGENT_UI=false
|
|
139
|
+
|
|
131
140
|
|
|
132
141
|
# BCP-47 locale tag passed to Playwright's launch `locale=` parameter
|
|
133
142
|
# (controls Accept-Language only — Chrome's UI language is forced to
|
|
@@ -59,6 +59,7 @@ Or invoke the wrapper: `/gflow:check`.
|
|
|
59
59
|
- Structured logging only (`structlog`) — **never** raw `print()` or `import logging` in `src/`.
|
|
60
60
|
- Errors as RFC 9457 Problem Details with stable per-class exit codes (3–27, e.g. 16 is the `DataStoreError` family, 19 `SceneConcatError`, 20 `FrameExtractionError`, 21 `ChainPartialError`, 22 `UpscaleUnavailableError`, 25 `FlowAgentUiError`). See `src/gflow_cli/errors.py::EXIT_CODE_MAP` for the complete mapping.
|
|
61
61
|
- 100-char line length, `ruff` configured. Imports sorted by `ruff` (isort rules).
|
|
62
|
+
- **YAGNI / least-code**: prefer the smallest change that works. No speculative abstractions (interface/factory with one implementation), no config or flags nobody sets, no dead constants/helpers, no reinventing the stdlib. Review carries this as its own lens — the **D14 over-engineering** dimension of [`pr-council-review`](skills/pr-council-review/SKILL.md) (baseline, always runs). Its rubric is portable; the `ponytail` plugin (see CONTRIBUTING) is an optional accelerant, not a dependency.
|
|
62
63
|
- **MCP & CLI Schema Symmetry**: Any updates or additions to user-facing CLI command parameters (e.g., `gflow image t2i`, `gflow video`) must be mirrored in the corresponding MCP tool definitions. Never add option/argument fields to Click commands without updating the MCP server implementation. This symmetry is enforced programmatically in CI via `tests/mcp/test_cli_parity.py` (every CLI leaf command needs a mapped MCP tool or an explicit, reasoned exemption) plus the schema checks in `tests/mcp/test_server.py`.
|
|
63
64
|
|
|
64
65
|
## PR instructions
|
|
@@ -7,6 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.34.0] — 2026-07-12
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- **`--ui-mode` / `GFLOW_CLI_UI_MODE` — the CLI can drive the Flow UI arm the command needs, both directions (#299).** Flow serves a **classic** composer or an **agentic** chat cohort, server-assigned and flapping per page load. Before generating, gflow now determines the **required** arm, switches to it as a prerequisite (classic↔agentic DOM toggle), **verifies** via a DOM re-probe, and — if the arm is unreachable — aborts *before* submitting with the new `UiModeUnavailableError` (**exit 28**, retryable), no credits spent. Values: `auto` (default; bind whatever renders), `classic` (require the hard aspect controls), `agentic` (require the chat surface). The required arm is also **inferred**: agent instructions (`-i`) are agentic-only, so they force agentic — closing the #267 gap where `-i` on a classic roll was *silently dropped* (now it either binds agentic or fails fast). Exposed as the **`--ui-mode` flag** on `gflow image t2i` / `i2i` (single-prompt; batch uses the env var) and the **`ui_mode` param** on the `gflow_generate_image` MCP tool; `--ui-mode classic` + `-i` is a fail-fast usage error. Grounded in the #299 spike (`docs/superpowers/spikes/2026-07-12-ui-cohort-backend-config.md`). Applies to every image generation via the shared driver seam. Honest ceiling: a server-side experiment can pin the arm, in which case the switch can't win — the abort still saves the credits.
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
|
|
18
|
+
- **`GFLOW_CLI_PREFER_CLASSIC` and `GFLOW_CLI_FORCE_AGENT_UI` are deprecated (#299)** in favor of `GFLOW_CLI_UI_MODE=classic` / `=agentic` (both still work, mapping to the new modes with a `DeprecationWarning`). **Behavior change:** the old `prefer_classic` silent fallback to agentic when the classic toggle was unavailable is gone — a classic-required run now aborts with exit 28 instead. Pipelines that relied on "always yields a file" from `PREFER_CLASSIC=1` must handle exit 28 (retry / switch profile / `GFLOW_CLI_UI_MODE=agentic`).
|
|
19
|
+
|
|
10
20
|
## [0.33.0] — 2026-07-12
|
|
11
21
|
|
|
12
22
|
### Added
|
|
@@ -1951,7 +1961,8 @@ shell-script template that branches on these codes.
|
|
|
1951
1961
|
|
|
1952
1962
|
First skeleton. Not functional end-to-end yet.
|
|
1953
1963
|
|
|
1954
|
-
[Unreleased]: https://github.com/ffroliva/gflow-cli/compare/v0.
|
|
1964
|
+
[Unreleased]: https://github.com/ffroliva/gflow-cli/compare/v0.34.0...HEAD
|
|
1965
|
+
[0.34.0]: https://github.com/ffroliva/gflow-cli/compare/v0.33.0...v0.34.0
|
|
1955
1966
|
[0.33.0]: https://github.com/ffroliva/gflow-cli/compare/v0.32.1...v0.33.0
|
|
1956
1967
|
[0.32.1]: https://github.com/ffroliva/gflow-cli/compare/v0.32.0...v0.32.1
|
|
1957
1968
|
[0.32.0]: https://github.com/ffroliva/gflow-cli/compare/v0.31.0...v0.32.0
|
|
@@ -102,6 +102,19 @@ pip install pre-commit && pre-commit install
|
|
|
102
102
|
|
|
103
103
|
The `.pre-commit-config.yaml` already ships ruff and the hygiene gate.
|
|
104
104
|
|
|
105
|
+
### Review lenses (over-engineering matters)
|
|
106
|
+
|
|
107
|
+
`gflow-cli` values **YAGNI / least-code** (see [AGENTS.md § Code style](AGENTS.md)):
|
|
108
|
+
the smallest change that works, no speculative abstractions, no dead code. This is a
|
|
109
|
+
first-class review dimension — **D14 over-engineering** in
|
|
110
|
+
[`pr-council-review`](skills/pr-council-review/SKILL.md), which always runs and carries
|
|
111
|
+
its own portable rubric.
|
|
112
|
+
|
|
113
|
+
Optionally, the `ponytail` Claude Code plugin (from the plugin marketplace) encodes
|
|
114
|
+
exactly this review taste — `/ponytail-review` audits a diff for over-engineering. It's a
|
|
115
|
+
**recommended, not required** accelerant: the D14 rubric applies with or without it, so no
|
|
116
|
+
contributor is blocked for lacking the plugin.
|
|
117
|
+
|
|
105
118
|
### SonarCloud quality gate
|
|
106
119
|
|
|
107
120
|
On top of the six gates, CI runs a **SonarCloud** analysis whose quality gate must be
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: gflow-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.34.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
|
|
@@ -231,13 +231,26 @@ GFLOW_CLI_HISTORY_PROMPTS=redacted gflow image t2i "confidential brief"
|
|
|
231
231
|
**Reverting:** unset the variable (or set `playwright`) — the default path is byte-identical to a build without this feature, with no profile migration.
|
|
232
232
|
**Security note:** the `patchright` extra ships a *patched Chromium driver* that handles your live Google session cookies; it is exact-pinned and treated as a security-review-required dependency. See [SECURITY.md § Dependencies](SECURITY.md).
|
|
233
233
|
|
|
234
|
-
### `
|
|
234
|
+
### `GFLOW_CLI_UI_MODE`
|
|
235
235
|
|
|
236
|
-
**What:**
|
|
237
|
-
**Values:**
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
236
|
+
**What:** Which Flow UI arm to use for generation. Flow serves a **classic** composer (hard crop/aspect controls) or an **agentic** chat cohort, server-assigned and flapping per page load ([#299](https://github.com/ffroliva/gflow-cli/issues/299)).
|
|
237
|
+
**Values:**
|
|
238
|
+
- `auto` (default) — bind whatever the composer renders.
|
|
239
|
+
- `classic` — require the classic composer (hard aspect controls). gflow switches to it, re-probes to verify, and if the arm is still agentic **aborts before submitting** with `UiModeUnavailableError` (**exit 28**) — no credits spent.
|
|
240
|
+
- `agentic` — require the agentic chat surface (needed for `-i` agent instructions). gflow switches to it, verifies, and aborts (exit 28) if it can't be reached.
|
|
241
|
+
**Default:** `auto`
|
|
242
|
+
**How it works:** before each generation, gflow determines the required arm, clicks the classic↔agentic toggle as a **prerequisite**, **verifies** with a DOM re-probe, then binds — or fails fast. The required arm is also **inferred**: `-i` instructions are agentic-only, so they force `agentic` automatically (and `--ui-mode classic` + `-i` is a hard conflict, not a silent drop).
|
|
243
|
+
**Why `classic`:** the agentic cohort treats aspect ratio as a soft prompt hint (portrait 9:16 can come back landscape). `classic` enforces it or fails fast instead of silently degrading.
|
|
244
|
+
**Retry note:** the cohort flaps per load, so an exit-28 abort is **retryable** — a re-run often lands the wanted arm. A server experiment can pin the arm, in which case it's unreachable from the client (the abort still saves the credits).
|
|
245
|
+
**Supersedes:** `GFLOW_CLI_PREFER_CLASSIC` and `GFLOW_CLI_FORCE_AGENT_UI` (below).
|
|
246
|
+
|
|
247
|
+
### `GFLOW_CLI_PREFER_CLASSIC` *(deprecated — use `GFLOW_CLI_UI_MODE=classic`)*
|
|
248
|
+
|
|
249
|
+
**Deprecated** in favor of [`GFLOW_CLI_UI_MODE`](#gflow_cli_ui_mode). `true` now maps to `ui_mode=classic` (emits a `DeprecationWarning`). **Behavior change:** the old silent fallback to agentic when the toggle was unavailable is gone — a classic-required run now **aborts with exit 28** instead of producing an agentic-cohort result. `GFLOW_CLI_UI_MODE` (and `--ui-mode`) take precedence when both are set.
|
|
250
|
+
|
|
251
|
+
### `GFLOW_CLI_FORCE_AGENT_UI` *(deprecated — use `GFLOW_CLI_UI_MODE=agentic`)*
|
|
252
|
+
|
|
253
|
+
**Deprecated** in favor of [`GFLOW_CLI_UI_MODE`](#gflow_cli_ui_mode). `true` maps to `ui_mode=agentic` (emits a `DeprecationWarning`). `-i` instructions already force agentic automatically, so this is rarely needed explicitly.
|
|
241
254
|
|
|
242
255
|
### `GFLOW_CLI_LOCALE`
|
|
243
256
|
|
|
@@ -122,7 +122,7 @@ Slash commands for Claude Code, stored in `.claude/commands/gflow/`. All prefixe
|
|
|
122
122
|
**"A gflow command hangs / fails — where do I start?"** → [DEBUGGING § Quick reference](DEBUGGING.md#quick-reference)
|
|
123
123
|
**"Flow's UI broke a selector — how do I diagnose it?"** → [DEBUGGING § Inspecting Flow's live UI](DEBUGGING.md#inspecting-flows-live-ui)
|
|
124
124
|
**"What does each `ui_automation.*` log event mean?"** → [DEBUGGING § Listener & HTTP-layer debugging](DEBUGGING.md#listener--http-layer-debugging)
|
|
125
|
-
**"What was actually live-verified for the latest release?"** → latest: [LIVE_VERIFICATION_v0.33.0](LIVE_VERIFICATION_v0.33.0.md) (**#287-follow-up picker fix proven live on the original repro** — the v0.32.1-failing `i2v <uuid> --project <crowded>` command now exits 0 with a real 3.0 MB `ftyp` mp4, `frame_ref_attached` + `video_saved`, zero uploads; **#241 jitter live-verified on both paths** — flag `--jitter 4-6` → `batch_jitter_sleep seconds=4.98`, and the new 0.5–1.5 s default → `seconds=1.47`, each firing exactly once between two t2i submissions; environment note: the denon82 cohort is now natively agentic and round-2 generations hit the pre-existing #281 `MediaAttributionError`, not a regression). Prior: [v0.32.1](LIVE_VERIFICATION_v0.32.1.md) (**#293 teardown fix live-verified credit-free** — error-path aborts leave ZERO chrome.exe holding the profile [3× leak reproduced pre-fix same day]; force-close fallback + ProfileLockedError translation unit-pinned; #283 wave logic fixes mock-verified to exact call counts). Prior: [v0.32.0](LIVE_VERIFICATION_v0.32.0.md) (**#287 UUID i2v frames proven live e2e** — an in-project asset selected by media UUID in the frame-slot dialog [frame_ref_attached, startImage bound on the wire, ZERO upload events] produced a real 720×1280 interpolation, resolving the #237 negative prior; foreign UUID → exit 9 pre-generation with screenshot; **#288 duration fail-fast proven live** — exit 23 pre-submit saved a 10-credit generation, and the debug screenshot confirmed the duration control is ABSENT from the cohort's settings popover [locale hypothesis refuted]; upload-400 exit-27 repro deferred-with-reason — the original rejected JPEG no longer exists). Prior: [v0.31.0](LIVE_VERIFICATION_v0.31.0.md) (**#281 wrong-media defenses live-verified in BOTH directions, credit-free** — correct attribution downloads with real wire metadata [seed, 768×1376]; the incident-class lazy-render ambiguity reproduced live and hard-stopped with `MediaAttributionError` exit 26 naming every candidate UUID, no file written; **#282 two-UUID-ref i2i proven e2e** — both freshly generated portrait UUIDs picker-selected into one scene with both canonical identities visually transferred). Prior: [v0.30.0](LIVE_VERIFICATION_v0.30.0.md) (**agentic-cohort image path + both fixes live-verified credit-free** — native 768×1376 stills, i2i-chain + canonical-ref identity hold; the character-create `DataIntegrityError` and the `prefer_classic` WARNING were observed live then fixed [recorder idempotent + INFO log]; MCP video-param feature deferred-with-reason on Veo credits, per the stills-only goal). Prior: [v0.29.0](LIVE_VERIFICATION_v0.29.0.md) (**persistent `gflow instructions` CRUD proven live e2e GREEN, credit-free** — 11-command sequence on a fresh project: add incl. `--ref <image-UUID>` attach, list/enable/disable, master toggle both ways, TOML `apply` destructive full-sync with `enabled=false` honored, `rm` with server card-id preserved across mutations; movie brief-sync code-path-verified via the same primitives, deferred-with-reason on credits; MCP `gflow_instructions_*` tools are thin adapters over the live-verified primitives). Prior: [v0.28.0](LIVE_VERIFICATION_v0.28.0.md) (**agent instructions `-i` now steer agentic generation — crayon e2e GREEN**: a style-neutral prompt + an enabled "crayon" card produced an unmistakable crayon drawing through the real transport; root causes were conversational phrasing + the `project_brief.enabled` master switch). Prior: [v0.27.1](LIVE_VERIFICATION_v0.27.1.md) (**v0.27.0 release follow-up fixes and documentation sync**). Prior: [v0.27.0](LIVE_VERIFICATION_v0.27.0.md) (**`[style]` block with named variants + prompt-aware resume — credit-free CLI verification**: real `movie run --dry-run` 3-way ledger proving resolved-style display, `skip (done)` on matching `style_hash`, and `re-run (style changed)` after a style edit; composition is local, wire path untouched, so no Veo credits spent — first credited styled run will confirm visually). Prior: [v0.26.0](LIVE_VERIFICATION_v0.26.0.md) (**image i2i by generated-image UUID proven live e2e GREEN** — the existing asset is *selected in place* by its media UUID, no duplicate upload, producing an i2i output that references it; plus generated-image `display_name` capture, credited @C1ph3r404). Prior: [v0.25.0](LIVE_VERIFICATION_v0.25.0.md) (**#237 remote-UUID i2v proven live e2e GREEN** — a real 8s 720×1280 interpolation from a generated image's UUID, after the picker-search attach was reworked to local upload; #240 home-`.env` matrix live; plus two silent-failure guards root-caused live: video-as-image download rejection and rejected-upload fail-loud). Prior: [v0.24.0](LIVE_VERIFICATION_v0.24.0.md) (--project parity across CLI + MCP — automated coverage; live gen auth-gated). Prior: [v0.23.0](LIVE_VERIFICATION_v0.23.0.md) (MCP generation wiring proven live end-to-end — tool→worker→real Flow REST→structured-error translation; final image-write blocked by an expired session, environmental. #222 macOS fix reporter-verified e2e on Apple Silicon). Prior: [v0.22.0](LIVE_VERIFICATION_v0.22.0.md) (Tools framework — automated/CI coverage complete; credit/key-gated live feature run is a pending owner gate, see the doc) · [v0.21.0](LIVE_VERIFICATION_v0.21.0.md) (MCP server over stdio + HTTP/SSE — credit-free protocol handshake; 4 tools / 2 prompts / 3 resources confirmed on stdout) · [v0.20.1](LIVE_VERIFICATION_v0.20.1.md) · [v0.20.0](LIVE_VERIFICATION_v0.20.0.md) · [v0.19.0](LIVE_VERIFICATION_v0.19.0.md) · [v0.18.0](LIVE_VERIFICATION_v0.18.0.md) · [v0.17.0](LIVE_VERIFICATION_v0.17.0.md) · [v0.16.0](LIVE_VERIFICATION_v0.16.0.md) · [v0.13.0](LIVE_VERIFICATION_v0.13.0.md) · [v0.12.0](LIVE_VERIFICATION_v0.12.0.md) · [v0.11.0](LIVE_VERIFICATION_v0.11.0.md) · [v0.10.0](LIVE_VERIFICATION_v0.10.0.md) · [v0.9.1](LIVE_VERIFICATION_v0.9.1.md) · [v0.9.0](LIVE_VERIFICATION_v0.9.0.md) · [v0.8.1](LIVE_VERIFICATION_v0.8.1.md) · [v0.7.0](LIVE_VERIFICATION_v0.7.0.md)
|
|
125
|
+
**"What was actually live-verified for the latest release?"** → latest: [LIVE_VERIFICATION_v0.34.0](LIVE_VERIFICATION_v0.34.0.md) (**#299 `--ui-mode` gate proven live, ZERO credits** — drove `get_ui_driver` directly over 4 real editor loads, never generated: bidirectional switch works [classic→agentic via `_force_agent_mode`, agentic→classic via `_exit_agent_mode`, each DOM-reverified], `agentic`-when-already-agentic is idempotent, and a timed-out toggle → **exit-28 fail-fast before submission**; deprecation behavior-change [`prefer_classic`→exit 28] confirmed). Prior: [v0.33.0](LIVE_VERIFICATION_v0.33.0.md) (**#287-follow-up picker fix proven live on the original repro** — the v0.32.1-failing `i2v <uuid> --project <crowded>` command now exits 0 with a real 3.0 MB `ftyp` mp4, `frame_ref_attached` + `video_saved`, zero uploads; **#241 jitter live-verified on both paths** — flag `--jitter 4-6` → `batch_jitter_sleep seconds=4.98`, and the new 0.5–1.5 s default → `seconds=1.47`, each firing exactly once between two t2i submissions; environment note: the denon82 cohort is now natively agentic and round-2 generations hit the pre-existing #281 `MediaAttributionError`, not a regression). Prior: [v0.32.1](LIVE_VERIFICATION_v0.32.1.md) (**#293 teardown fix live-verified credit-free** — error-path aborts leave ZERO chrome.exe holding the profile [3× leak reproduced pre-fix same day]; force-close fallback + ProfileLockedError translation unit-pinned; #283 wave logic fixes mock-verified to exact call counts). Prior: [v0.32.0](LIVE_VERIFICATION_v0.32.0.md) (**#287 UUID i2v frames proven live e2e** — an in-project asset selected by media UUID in the frame-slot dialog [frame_ref_attached, startImage bound on the wire, ZERO upload events] produced a real 720×1280 interpolation, resolving the #237 negative prior; foreign UUID → exit 9 pre-generation with screenshot; **#288 duration fail-fast proven live** — exit 23 pre-submit saved a 10-credit generation, and the debug screenshot confirmed the duration control is ABSENT from the cohort's settings popover [locale hypothesis refuted]; upload-400 exit-27 repro deferred-with-reason — the original rejected JPEG no longer exists). Prior: [v0.31.0](LIVE_VERIFICATION_v0.31.0.md) (**#281 wrong-media defenses live-verified in BOTH directions, credit-free** — correct attribution downloads with real wire metadata [seed, 768×1376]; the incident-class lazy-render ambiguity reproduced live and hard-stopped with `MediaAttributionError` exit 26 naming every candidate UUID, no file written; **#282 two-UUID-ref i2i proven e2e** — both freshly generated portrait UUIDs picker-selected into one scene with both canonical identities visually transferred). Prior: [v0.30.0](LIVE_VERIFICATION_v0.30.0.md) (**agentic-cohort image path + both fixes live-verified credit-free** — native 768×1376 stills, i2i-chain + canonical-ref identity hold; the character-create `DataIntegrityError` and the `prefer_classic` WARNING were observed live then fixed [recorder idempotent + INFO log]; MCP video-param feature deferred-with-reason on Veo credits, per the stills-only goal). Prior: [v0.29.0](LIVE_VERIFICATION_v0.29.0.md) (**persistent `gflow instructions` CRUD proven live e2e GREEN, credit-free** — 11-command sequence on a fresh project: add incl. `--ref <image-UUID>` attach, list/enable/disable, master toggle both ways, TOML `apply` destructive full-sync with `enabled=false` honored, `rm` with server card-id preserved across mutations; movie brief-sync code-path-verified via the same primitives, deferred-with-reason on credits; MCP `gflow_instructions_*` tools are thin adapters over the live-verified primitives). Prior: [v0.28.0](LIVE_VERIFICATION_v0.28.0.md) (**agent instructions `-i` now steer agentic generation — crayon e2e GREEN**: a style-neutral prompt + an enabled "crayon" card produced an unmistakable crayon drawing through the real transport; root causes were conversational phrasing + the `project_brief.enabled` master switch). Prior: [v0.27.1](LIVE_VERIFICATION_v0.27.1.md) (**v0.27.0 release follow-up fixes and documentation sync**). Prior: [v0.27.0](LIVE_VERIFICATION_v0.27.0.md) (**`[style]` block with named variants + prompt-aware resume — credit-free CLI verification**: real `movie run --dry-run` 3-way ledger proving resolved-style display, `skip (done)` on matching `style_hash`, and `re-run (style changed)` after a style edit; composition is local, wire path untouched, so no Veo credits spent — first credited styled run will confirm visually). Prior: [v0.26.0](LIVE_VERIFICATION_v0.26.0.md) (**image i2i by generated-image UUID proven live e2e GREEN** — the existing asset is *selected in place* by its media UUID, no duplicate upload, producing an i2i output that references it; plus generated-image `display_name` capture, credited @C1ph3r404). Prior: [v0.25.0](LIVE_VERIFICATION_v0.25.0.md) (**#237 remote-UUID i2v proven live e2e GREEN** — a real 8s 720×1280 interpolation from a generated image's UUID, after the picker-search attach was reworked to local upload; #240 home-`.env` matrix live; plus two silent-failure guards root-caused live: video-as-image download rejection and rejected-upload fail-loud). Prior: [v0.24.0](LIVE_VERIFICATION_v0.24.0.md) (--project parity across CLI + MCP — automated coverage; live gen auth-gated). Prior: [v0.23.0](LIVE_VERIFICATION_v0.23.0.md) (MCP generation wiring proven live end-to-end — tool→worker→real Flow REST→structured-error translation; final image-write blocked by an expired session, environmental. #222 macOS fix reporter-verified e2e on Apple Silicon). Prior: [v0.22.0](LIVE_VERIFICATION_v0.22.0.md) (Tools framework — automated/CI coverage complete; credit/key-gated live feature run is a pending owner gate, see the doc) · [v0.21.0](LIVE_VERIFICATION_v0.21.0.md) (MCP server over stdio + HTTP/SSE — credit-free protocol handshake; 4 tools / 2 prompts / 3 resources confirmed on stdout) · [v0.20.1](LIVE_VERIFICATION_v0.20.1.md) · [v0.20.0](LIVE_VERIFICATION_v0.20.0.md) · [v0.19.0](LIVE_VERIFICATION_v0.19.0.md) · [v0.18.0](LIVE_VERIFICATION_v0.18.0.md) · [v0.17.0](LIVE_VERIFICATION_v0.17.0.md) · [v0.16.0](LIVE_VERIFICATION_v0.16.0.md) · [v0.13.0](LIVE_VERIFICATION_v0.13.0.md) · [v0.12.0](LIVE_VERIFICATION_v0.12.0.md) · [v0.11.0](LIVE_VERIFICATION_v0.11.0.md) · [v0.10.0](LIVE_VERIFICATION_v0.10.0.md) · [v0.9.1](LIVE_VERIFICATION_v0.9.1.md) · [v0.9.0](LIVE_VERIFICATION_v0.9.0.md) · [v0.8.1](LIVE_VERIFICATION_v0.8.1.md) · [v0.7.0](LIVE_VERIFICATION_v0.7.0.md)
|
|
126
126
|
**"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.
|
|
127
127
|
**"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)
|
|
128
128
|
**"What was live-verified for the video-download feature (#29)?"** → [LIVE_VERIFICATION_video_download](LIVE_VERIFICATION_video_download.md)
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# Live verification — v0.34.0 (2026-07-12)
|
|
2
|
+
|
|
3
|
+
The release's one user-facing feature — the `--ui-mode` / `GFLOW_CLI_UI_MODE`
|
|
4
|
+
ensure-required-mode gate (#299) — exercised against live Flow on the merged
|
|
5
|
+
`develop` tip, profile `denon82`. **Zero credits:** the production
|
|
6
|
+
`get_ui_driver(page, ui_mode=…)` gate was driven directly over 4 real editor
|
|
7
|
+
loads; generation was **never** called.
|
|
8
|
+
|
|
9
|
+
Ledger adapted for a control-plane feature (no generated artifact): exit-code /
|
|
10
|
+
raise outcome · structlog switch invariants · observed DOM arm transition
|
|
11
|
+
(before → after) · a re-runnable probe. `scratchpad/ui_mode_gate_e2e.py`.
|
|
12
|
+
|
|
13
|
+
## What was confirmed (all four gate behaviors)
|
|
14
|
+
|
|
15
|
+
| Requested | Live mount | Switch attempt (structlog) | Outcome |
|
|
16
|
+
|---|---|---|---|
|
|
17
|
+
| `auto` | agentic | (none) | binds `agentic` (whatever renders) |
|
|
18
|
+
| `agentic` | classic | `ui_driver.ui_mode.attempt_force_agent` → `ui_automation.agent_mode_forced activated=True` | arm before=classic → **after=agentic**, binds `agentic` |
|
|
19
|
+
| `classic` | agentic | `ui_driver.ui_mode.attempt_exit_agent` → `ui_automation_video.exited_agent_mode` | arm before=agentic → **after=classic**, binds `classic` |
|
|
20
|
+
| `agentic` | agentic | `ui_automation.agent_mode_already_active` | idempotent no-op, binds `agentic` |
|
|
21
|
+
| `classic` | agentic (toggle click **timed out**: `agent_toggle_probe_failed`) | switch did not take | **`UiModeUnavailableError` — exit 28 fail-fast** (`requested=classic`), before any submission |
|
|
22
|
+
|
|
23
|
+
- **Bidirectional switch proven live** — classic→agentic (`_force_agent_mode`)
|
|
24
|
+
and agentic→classic (`_exit_agent_mode`), each verified by a DOM re-probe.
|
|
25
|
+
- **Fail-fast proven live** — when the toggle genuinely could not reach the
|
|
26
|
+
required arm, the gate raised exit 28 *before* submitting, spending no credits
|
|
27
|
+
(the money-shot: the honest terminal state fires on a real unreachable arm).
|
|
28
|
+
- **Inference / flag / MCP surfaces** — covered by 1529 automated tests
|
|
29
|
+
(flag→request threading, both CLI guards, worker payload→request); the CLI
|
|
30
|
+
guards (`--ui-mode classic` + `-i`, `--ui-mode` single-prompt-only) were also
|
|
31
|
+
smoke-verified at exit 2.
|
|
32
|
+
|
|
33
|
+
`denon82` rolled agentic on most loads (the current natively-agentic cohort
|
|
34
|
+
behavior), which conveniently exercised both switch directions in one run.
|
|
35
|
+
|
|
36
|
+
## Behavior-change note (carried from the CHANGELOG)
|
|
37
|
+
|
|
38
|
+
`GFLOW_CLI_PREFER_CLASSIC` is deprecated → maps to `--ui-mode classic`, and the
|
|
39
|
+
old silent agentic fallback is gone: a classic-required run now aborts with exit
|
|
40
|
+
28 instead of producing an agentic-cohort result. Verified above (the timed-out
|
|
41
|
+
case is exactly that abort).
|
|
42
|
+
|
|
43
|
+
## Not verified this cycle
|
|
44
|
+
|
|
45
|
+
- The exit-28 abort's *auto-reload-retry* is intentionally **not implemented**
|
|
46
|
+
(deferred; see the design note) — today the retry is the user re-running the
|
|
47
|
+
command. Nothing to verify.
|
|
48
|
+
- Item 3a/3b (agentic driver parity) and item 2 (enforce-via-mutation) are not in
|
|
49
|
+
this release.
|
|
@@ -184,6 +184,11 @@ Options:
|
|
|
184
184
|
-t, --tool NAME[:k=v] Apply a prompt tool before generating, e.g.
|
|
185
185
|
`creative-director:style=cinema`. Repeatable; applied
|
|
186
186
|
per prompt on multi-prompt/batch. See "Prompt tools".
|
|
187
|
+
--ui-mode [auto|classic|agentic]
|
|
188
|
+
Require a Flow UI arm: classic (hard aspect
|
|
189
|
+
controls) / agentic (chat surface; forced by -i) /
|
|
190
|
+
auto (default). Aborts exit 28 if unreachable.
|
|
191
|
+
Single-prompt only; batch uses GFLOW_CLI_UI_MODE.
|
|
187
192
|
--profile NAME Profile name (overrides default).
|
|
188
193
|
```
|
|
189
194
|
|
|
@@ -1249,6 +1254,7 @@ shell scripts can branch on the failure mode without parsing stderr.
|
|
|
1249
1254
|
| `25` | `FlowAgentUiError` | The profile is on Flow's Agentic UI cohort and the classic media panel is unrecoverable for this operation | Use a Classic-cohort profile; see KNOWN_ISSUES on the agentic cohort |
|
|
1250
1255
|
| `26` | `MediaAttributionError` | Generated media could not be reliably attributed to this request (issue #281) | Re-run; a dedicated project with fewer pre-existing assets avoids the ambiguity |
|
|
1251
1256
|
| `27` | `MediaUploadRejectedError` | Flow's upload endpoint refused the input file (`uploadImage` 4xx, issue #287) | Re-encode the image (`ffmpeg -q:v 2 -map_metadata -1`), or reference the asset by its media UUID |
|
|
1257
|
+
| `28` | `UiModeUnavailableError` | The Flow UI arm this command required (`GFLOW_CLI_UI_MODE`, or inferred — `-i` forces agentic) couldn't be reached after a switch attempt; aborted before submitting — no credits spent (issue #299) | Retry (the cohort flaps per load); try another `--profile`; or relax `GFLOW_CLI_UI_MODE` |
|
|
1252
1258
|
| `130`| SIGINT | User-interrupted (Ctrl-C) | — |
|
|
1253
1259
|
|
|
1254
1260
|
**Exit code 16 — data store / migration error.** Fires when:
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# Spike evidence — UI-cohort backend config surface (issue #299 gate)
|
|
2
|
+
|
|
3
|
+
**Date:** 2026-07-12 · **Verdict: GO (partial) — the UI arm IS a readable, persisted
|
|
4
|
+
backend setting; enforcement is a captured mutation away.** This overturns the
|
|
5
|
+
`AGENT_UI_RECON.md` § Gating conclusion that "there is no client-readable cohort
|
|
6
|
+
signal."
|
|
7
|
+
|
|
8
|
+
## Method
|
|
9
|
+
|
|
10
|
+
Automatable half of the #299 spike (H1/H3), zero credits — navigation only, no
|
|
11
|
+
Generate click. `scratchpad/ui_cohort_spike.py`: launched a headless persistent
|
|
12
|
+
Chrome context on `profile_denon82`, cold-loaded the editor
|
|
13
|
+
(`/project/f6caf027…`) **3×**, and per load captured (a) the UI arm via the
|
|
14
|
+
production `detect_ui_mode` probe, (b) the client gating surface (`__NEXT_DATA__`
|
|
15
|
+
pageProps, localStorage, sessionStorage, cookie names), and (c) every network
|
|
16
|
+
response, with bounded JSON bodies for config/preference/RPC-looking URLs.
|
|
17
|
+
|
|
18
|
+
The recon (2026-06-14) inspected localStorage / cookies / `__NEXT_DATA__` pageProp
|
|
19
|
+
**keys** and correctly found no arm flag there. It did **not** read the **tRPC
|
|
20
|
+
query response bodies** — which is where the arm actually lives.
|
|
21
|
+
|
|
22
|
+
## Result
|
|
23
|
+
|
|
24
|
+
- **Arm this session:** `classic` on all 3 headless loads — yet today's earlier
|
|
25
|
+
CLI e2e (also headless, same profile) hit `agentic`. So the cohort **flaps**;
|
|
26
|
+
denon82 is **not** permanently agentic.
|
|
27
|
+
- **`GET /api/trpc/videoFx.getUserSettings`** →
|
|
28
|
+
`{"isAgentModeToggled": false, "isChatPanelOpen": false, "tilesDisplayMode":
|
|
29
|
+
"grid", "completedOnboardingIds":["AGENT","MODEL"], …}` — a **per-user persisted
|
|
30
|
+
setting**. `isAgentModeToggled:false` is consistent with the 3 classic loads.
|
|
31
|
+
- **`GET /api/trpc/videoFx.getFlowAppConfig`** → `"agentModeDefaultState":
|
|
32
|
+
"agent_off"`, plus `"activeExperimentIds":[106077941, 105798603, …]` and a raft
|
|
33
|
+
of `isXEnabled` feature flags — the app-level default + server experiment list.
|
|
34
|
+
- **`GET /api/trpc/general.fetchUserPreferences`** → history/product-improvement
|
|
35
|
+
only (no arm).
|
|
36
|
+
- Endpoints seen on cold load are **all GET** (plus a `general.submitBatchLog`
|
|
37
|
+
telemetry POST). No mode-mutation fired — it only fires on the Agent-pill click.
|
|
38
|
+
|
|
39
|
+
## Interpretation
|
|
40
|
+
|
|
41
|
+
The effective arm is best modelled as:
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
effective_arm = experiment_override(activeExperimentIds) # server, may force agentic
|
|
45
|
+
?? user_setting(isAgentModeToggled) # persisted, client-readable
|
|
46
|
+
?? app_default(agentModeDefaultState) # "agent_off" today
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
- **H1 — CONFIRMED.** The intended arm is **readable pre-generation** from
|
|
50
|
+
`getUserSettings.isAgentModeToggled` + `getFlowAppConfig.agentModeDefaultState`
|
|
51
|
+
/ `activeExperimentIds`, via an authenticated in-page `fetch` on the editor we
|
|
52
|
+
already load. DOM `detect_ui_mode` stays the ground-truth post-render check;
|
|
53
|
+
the tRPC read gives a *pre-render prediction* + a diagnosable "why".
|
|
54
|
+
- **H2 — STRONGLY INDICATED, not yet captured.** `isAgentModeToggled` is a
|
|
55
|
+
persisted tRPC-backed setting, so the Agent pill flips it through a mutation
|
|
56
|
+
(expected `videoFx.setUserSettings` / `updateUserSettings` shape). It does not
|
|
57
|
+
fire on load, so its exact name/payload needs one pill-click capture.
|
|
58
|
+
- **H3 — residual.** If an entry in `activeExperimentIds` force-assigns agentic,
|
|
59
|
+
setting `isAgentModeToggled:false` will not override it. Reading still lets us
|
|
60
|
+
**fail fast** before spending; enforcement is then partial, not guaranteed.
|
|
61
|
+
|
|
62
|
+
## Decision
|
|
63
|
+
|
|
64
|
+
**GO into `/gflow:predict`** with this evidence. Recommended scope, in reliability
|
|
65
|
+
order:
|
|
66
|
+
|
|
67
|
+
1. **Read-and-fail-fast (no mutation needed, ships on H1 alone):** the `--ui-mode`
|
|
68
|
+
policy (#299 item 1) gains a pre-submission tRPC read of `isAgentModeToggled` /
|
|
69
|
+
`agentModeDefaultState`; a strict `classic` request aborts cleanly (typed
|
|
70
|
+
error, zero credits) when the predicted/probed arm is agentic. Deterministic,
|
|
71
|
+
low-risk.
|
|
72
|
+
2. **Enforce (needs the H2 capture):** replace the best-effort pill-click in
|
|
73
|
+
`get_ui_driver(prefer_classic=True)` with the captured `setUserSettings`
|
|
74
|
+
mutation to persist `isAgentModeToggled:false`, then re-probe. Predict-gated
|
|
75
|
+
(transport change).
|
|
76
|
+
3. **Driver parity (H3 fallback, from #299 item 2):** wire-response attribution +
|
|
77
|
+
content-type retry — the fix when an experiment pins agentic and enforcement
|
|
78
|
+
can't win.
|
|
79
|
+
|
|
80
|
+
## Follow-up needed (manual, blocked on a human at the keyboard)
|
|
81
|
+
|
|
82
|
+
`gflow-agent-browser-spike/scripts/capture-agent-ui.ps1` already automates the
|
|
83
|
+
capture around a pill click + one generation. Run it on a **pill-rendering
|
|
84
|
+
cohort** (try `promo-denon82` / `test_acc`; toggle the Agent pill) to record the
|
|
85
|
+
mutation endpoint + payload (H2) and, ideally, an `agentic` load to confirm the
|
|
86
|
+
arm correlates with `isAgentModeToggled:true`. That closes H2/H3 before predict
|
|
87
|
+
finalizes item 2.
|
|
@@ -6,7 +6,7 @@ description: Multi-dimensional LLM council review of an open PR (default) or a l
|
|
|
6
6
|
|
|
7
7
|
# `pr-council-review` — PR Council Review skill
|
|
8
8
|
|
|
9
|
-
Council-driven PR review. Dispatches **
|
|
9
|
+
Council-driven PR review. Dispatches **6 baseline + N adaptive** parallel reviewers, each scoped to one dimension, each invoking the relevant Claude Code specialized skill (e.g. `security-review`, `code-review`, `verify`), then synthesizes a single consensus verdict.
|
|
10
10
|
|
|
11
11
|
This skill is the canonical body. The Claude Code slash command at `.claude/commands/gflow/pr-council-review.md` is a thin wrapper that invokes this skill. Non-Claude tools (Gemini CLI / Codex / Cursor / Aider) can consume this SKILL.md directly via their own skill loaders.
|
|
12
12
|
|
|
@@ -117,8 +117,9 @@ Pull in parallel via `ctx_batch_execute`:
|
|
|
117
117
|
| **D11 — Release-gate compliance** | adaptive | `pyproject.toml`, `src/gflow_cli/__init__.py`, `.github/workflows/`, `release/*` branch |
|
|
118
118
|
| **D12 — BDD step-stub signatures** | adaptive | any path under `tests/features/` |
|
|
119
119
|
| **D13 — Dev / release scripts** | adaptive | any path under `scripts/` |
|
|
120
|
+
| **D14 — Over-engineering / YAGNI** | ✅ baseline (NEW v3) | always |
|
|
120
121
|
|
|
121
|
-
**Baseline floor is non-negotiable.** D1–D5 ALWAYS run. **Docs-only PRs** (100% paths under `*.md`, `docs/**`, `CHANGELOG.md`, `README.md`, `LICENSE`, `AUTHORS`) → D4 reframes from "test code coverage" to "docs-verification"; D5 still runs unchanged.
|
|
122
|
+
**Baseline floor is non-negotiable.** D1–D5 and D14 ALWAYS run. **Docs-only PRs** (100% paths under `*.md`, `docs/**`, `CHANGELOG.md`, `README.md`, `LICENSE`, `AUTHORS`) → D4 reframes from "test code coverage" to "docs-verification"; D5 still runs unchanged.
|
|
122
123
|
|
|
123
124
|
---
|
|
124
125
|
|
|
@@ -145,6 +146,9 @@ Each agent is a `general-purpose` agent (only subagent type that supports arbitr
|
|
|
145
146
|
| D11 Release-gate | (none — direct config inspection) | |
|
|
146
147
|
| D12 BDD | (none — direct stub-signature inspection) | |
|
|
147
148
|
| D13 Scripts | (none — direct script inspection) | |
|
|
149
|
+
| D14 Over-engineering | `ponytail:ponytail-review` *(soft dep — invoke if installed; else apply the inline YAGNI rubric in § Per-dimension specifics)* | "Should this code exist at all?" — the lens D1–D2 don't cover |
|
|
150
|
+
|
|
151
|
+
**On the D14 soft dependency:** `ponytail:ponytail-review` is a user-local plugin, not shipped with this repo, so it is **optional** (same pattern as the `agy` extra reviewer in `issue-resolve`). The over-engineering **lens is owned by this skill** (the rubric below); the plugin only accelerates it. An agent without the plugin applies the rubric directly and still produces a D14 verdict — never skip D14 because the plugin is absent.
|
|
148
152
|
|
|
149
153
|
### Per-agent prompt skeleton (mandatory v2 changes in bold)
|
|
150
154
|
|
|
@@ -213,6 +217,7 @@ If you are NOT sure a finding is real because it depends on file content, VERIFY
|
|
|
213
217
|
| D11 | `[[release-back-merge-gap-recovery]]`, `[[wheel-build-sanity-gate]]`, `[[pypi-rejected-filename-reusable]]`, `[[draft-pr-merge-trap]]` |
|
|
214
218
|
| D12 | `[[bdd-stubs-mirror-runtime-signatures]]` |
|
|
215
219
|
| D13 | `[[wheel-build-sanity-gate]]` |
|
|
220
|
+
| D14 | (none mandatory; apply the YAGNI rubric below) |
|
|
216
221
|
|
|
217
222
|
### Per-dimension specifics
|
|
218
223
|
|
|
@@ -238,6 +243,13 @@ If you are NOT sure a finding is real because it depends on file content, VERIFY
|
|
|
238
243
|
- **D11 Release-gate:** version match `pyproject.toml` ↔ `src/gflow_cli/__init__.py` (RED if drift). `[Unreleased]` emptied + new version added. Wheel build clean. Back-merge gap addressed.
|
|
239
244
|
- **D12 BDD:** new `_run_*` kwarg → mirror in `tests/features/_fake_*` stubs (silent TypeError trap).
|
|
240
245
|
- **D13 Scripts:** Windows-clean (memory `[[windows-dev-quirks]]`); release scripts include wheel-build sanity gate.
|
|
246
|
+
- **D14 Over-engineering / YAGNI:** *should this code exist at all?* — the lens D1 (correctness) and D2 (quality) don't ask. If `ponytail:ponytail-review` is installed, invoke it; otherwise apply this rubric directly to the **added** lines:
|
|
247
|
+
- **Dead / orphaned:** a constant, helper, field, or branch with no live caller after the change (e.g. a module constant only its own definition + a docstring reference now use). Cut it.
|
|
248
|
+
- **Speculative flexibility:** an interface/factory/abstraction with one implementation, a config knob or flag nobody sets, a parameter only ever passed one value, a layer with one caller. Inline until a second caller exists.
|
|
249
|
+
- **Reinvented stdlib / platform:** a hand-rolled parser/validator/date-format the standard library or the platform already ships. Name the built-in.
|
|
250
|
+
- **One-caller indirection:** a wrapper function whose only value is a test seam, when the callee could be patched directly (match how sibling code does it).
|
|
251
|
+
- **Scaffolding "for later":** boilerplate, placeholder modules, or generality added for a use case not in this PR.
|
|
252
|
+
- Output the concrete cut per finding (`file:Lline: delete/inline/shrink — what replaces it`) and, when meaningful, `net: -N lines possible`. A single smoke test / `assert`-based self-check is the minimum, never flag it as bloat. RED only for genuinely dead/unreachable code; over-generality is Nice-to-have unless it's load-bearing.
|
|
241
253
|
|
|
242
254
|
---
|
|
243
255
|
|
|
@@ -303,7 +315,7 @@ Always end with an `AskUserQuestion`.
|
|
|
303
315
|
|
|
304
316
|
> **Provenance:** v1 protocol validated on PR #93 (locale selectors, 2026-05-26). v2 evolved 2026-05-27 after running on PR #95 surfaced two real defects: (a) sub-agents read stale working-tree files producing 5+ false positives (memory `[[pr-council-review-stale-tree-reads]]`), (b) baseline missed memory-hygiene as a dimension. Both fixed in v2.
|
|
305
317
|
|
|
306
|
-
- Council baseline =
|
|
318
|
+
- Council baseline = 6 dimensions (D1–D5 + D14 over-engineering). Adaptive ceiling = D6–D13. Going beyond ~14 adds noise faster than signal — split into two reviews instead.
|
|
307
319
|
- Sub-agents are `general-purpose` agents that invoke specialized skills (`security-review`, `code-review`, `verify`, `review`) inside their prompt for dimension-specific capability.
|
|
308
320
|
- The command is **stateless** and **read-only** — concurrent invocations on different PRs don't share data. No `gh pr merge`, no `git push`, no `gh pr close`.
|
|
309
321
|
- **Idempotence:** same PR SHA → comparable verdicts on different days. Drift usually means memory grew new precedents or the mandatory-slug table needs an update.
|
|
@@ -30,6 +30,7 @@ if TYPE_CHECKING:
|
|
|
30
30
|
from collections.abc import Mapping
|
|
31
31
|
from pathlib import Path
|
|
32
32
|
|
|
33
|
+
from gflow_cli.config import UiMode
|
|
33
34
|
from gflow_cli.tools.invocation import AppliedTool
|
|
34
35
|
|
|
35
36
|
__all__ = [
|
|
@@ -431,6 +432,9 @@ class GenerateImageRequest:
|
|
|
431
432
|
# ignored by the body builders. (PR2 §8)
|
|
432
433
|
original_prompt: str | None = None
|
|
433
434
|
tool: AppliedTool | None = None
|
|
435
|
+
# Requested Flow UI arm (#299) from --ui-mode; None → resolve from
|
|
436
|
+
# GFLOW_CLI_UI_MODE / default at the transport. Not sent on the wire.
|
|
437
|
+
ui_mode: UiMode | None = None
|
|
434
438
|
|
|
435
439
|
def __post_init__(self) -> None:
|
|
436
440
|
if not self.prompt or not self.prompt.strip():
|
|
@@ -30,6 +30,7 @@ import structlog
|
|
|
30
30
|
|
|
31
31
|
from gflow_cli.api.transports.drivers.agentic import AgenticFlowUiDriver
|
|
32
32
|
from gflow_cli.api.transports.drivers.classic import ClassicFlowUiDriver
|
|
33
|
+
from gflow_cli.config import UiMode
|
|
33
34
|
|
|
34
35
|
if TYPE_CHECKING:
|
|
35
36
|
from collections.abc import Iterable
|
|
@@ -128,32 +129,60 @@ async def get_ui_driver(
|
|
|
128
129
|
*,
|
|
129
130
|
timeout_s: float | None = None,
|
|
130
131
|
poll_interval_s: float | None = None,
|
|
131
|
-
|
|
132
|
+
ui_mode: UiMode = UiMode.AUTO,
|
|
132
133
|
) -> FlowUiDriver:
|
|
133
134
|
"""Probe the DOM and return the matching :class:`FlowUiDriver`.
|
|
134
135
|
|
|
136
|
+
``ui_mode`` (issue #299) is the caller's policy:
|
|
137
|
+
* ``AUTO`` — bind whatever the composer renders.
|
|
138
|
+
* ``CLASSIC`` — attempt to recover the classic composer (best-effort exit
|
|
139
|
+
of the agentic chat), then, if the arm is STILL agentic, raise
|
|
140
|
+
``UiModeUnavailableError`` (exit 28) **before** any generation — zero
|
|
141
|
+
credits. The DOM probe is the authority; the arm flaps per load, so a
|
|
142
|
+
re-run often lands classic.
|
|
143
|
+
* ``AGENTIC`` — switch the composer to agentic, verify, and raise
|
|
144
|
+
``UiModeUnavailableError`` if the arm can't be reached.
|
|
145
|
+
|
|
135
146
|
Call per generation — the cohort flaps per page load, so a cached driver
|
|
136
147
|
goes stale on the next navigation / batch item.
|
|
137
148
|
"""
|
|
138
|
-
|
|
149
|
+
# Prerequisite switch: when a specific arm is required and the current one
|
|
150
|
+
# differs, attempt the DOM toggle for that direction (best-effort — the
|
|
151
|
+
# server can pin the arm). The re-probe below VERIFIES whether it took.
|
|
152
|
+
if ui_mode is UiMode.CLASSIC:
|
|
139
153
|
from gflow_cli.api.transports.ui_automation_video import (
|
|
140
154
|
VideoGenerationMixin,
|
|
141
155
|
)
|
|
142
156
|
from gflow_cli.errors import FlowAgentUiError
|
|
143
157
|
|
|
144
158
|
try:
|
|
145
|
-
log.info("ui_driver.
|
|
159
|
+
log.info("ui_driver.ui_mode.attempt_exit_agent")
|
|
146
160
|
await VideoGenerationMixin._exit_agent_mode(page) # type: ignore[reportPrivateUsage]
|
|
147
161
|
except FlowAgentUiError as exc:
|
|
148
|
-
# Expected:
|
|
149
|
-
# client-side.
|
|
150
|
-
|
|
151
|
-
log.info("ui_driver.prefer_classic.cohort_natively_agentic", detail=str(exc))
|
|
162
|
+
# Expected: a server-pinned agentic cohort cannot be exited
|
|
163
|
+
# client-side. The verify check below turns this into a clean abort.
|
|
164
|
+
log.info("ui_driver.ui_mode.cohort_natively_agentic", detail=str(exc))
|
|
152
165
|
except Exception as exc:
|
|
153
|
-
log.warning("ui_driver.
|
|
166
|
+
log.warning("ui_driver.ui_mode.exit_agent_failed", error=str(exc))
|
|
167
|
+
elif ui_mode is UiMode.AGENTIC:
|
|
168
|
+
from gflow_cli.api.transports.ui_automation import UiAutomationTransport
|
|
169
|
+
|
|
170
|
+
try:
|
|
171
|
+
log.info("ui_driver.ui_mode.attempt_force_agent")
|
|
172
|
+
await UiAutomationTransport._force_agent_mode(page) # type: ignore[reportPrivateUsage]
|
|
173
|
+
except Exception as exc: # noqa: BLE001 - best-effort switch, verified below
|
|
174
|
+
log.warning("ui_driver.ui_mode.force_agent_failed", error=str(exc))
|
|
175
|
+
|
|
176
|
+
# Verify: re-probe the DOM ground truth after any switch attempt.
|
|
177
|
+
from gflow_cli.errors import UiModeUnavailableError
|
|
154
178
|
|
|
155
179
|
mode = await detect_ui_mode(page, timeout_s=timeout_s, poll_interval_s=poll_interval_s)
|
|
156
|
-
log.info("ui_driver.bound", mode=mode)
|
|
180
|
+
log.info("ui_driver.bound", mode=mode, ui_mode=ui_mode.value)
|
|
157
181
|
if mode == "agentic":
|
|
182
|
+
if ui_mode is UiMode.CLASSIC:
|
|
183
|
+
raise UiModeUnavailableError(UiMode.CLASSIC)
|
|
158
184
|
return AgenticFlowUiDriver()
|
|
185
|
+
# classic rendered
|
|
186
|
+
if ui_mode is UiMode.AGENTIC:
|
|
187
|
+
raise UiModeUnavailableError(UiMode.AGENTIC)
|
|
159
188
|
return ClassicFlowUiDriver()
|
|
@@ -16,7 +16,6 @@ from __future__ import annotations
|
|
|
16
16
|
import asyncio
|
|
17
17
|
import hashlib
|
|
18
18
|
import json
|
|
19
|
-
import os
|
|
20
19
|
import random
|
|
21
20
|
import re
|
|
22
21
|
import time
|
|
@@ -208,10 +207,9 @@ SUBMIT_BUTTON_SELECTORS = (
|
|
|
208
207
|
# agentic chat layout — the ``crop_*`` media trigger disappears and the ``tune``
|
|
209
208
|
# settings gear + ``expand_content`` open button appear. Captured live
|
|
210
209
|
# 2026-06-14 via ``scripts/e2e/capture_agent_toggle.py`` (cropPresent true→false,
|
|
211
|
-
# tune false→true).
|
|
212
|
-
# drive the agentic path regardless of the
|
|
213
|
-
# no client-readable flag
|
|
214
|
-
AGENT_FORCE_ENV_VAR = "GFLOW_CLI_FORCE_AGENT_UI"
|
|
210
|
+
# tune false→true). Reached via ``GFLOW_CLI_UI_MODE=agentic`` (or an inferred
|
|
211
|
+
# agentic requirement) to drive the agentic path regardless of the
|
|
212
|
+
# server-assigned A/B cohort (which has no client-readable flag).
|
|
215
213
|
AGENT_EXPAND_BUTTON_SELECTOR = "button:has(i.google-symbols:text-is('expand_content'))"
|
|
216
214
|
|
|
217
215
|
# _force_agent_mode: after clicking the Agent toggle, POLL for the ``tune``
|
|
@@ -1058,7 +1056,7 @@ class UiAutomationTransport(VideoGenerationMixin):
|
|
|
1058
1056
|
async def _force_agent_mode(page: Page) -> bool:
|
|
1059
1057
|
"""Force the agentic composer by clicking the in-composer Agent toggle.
|
|
1060
1058
|
|
|
1061
|
-
Opt-in helper (
|
|
1059
|
+
Opt-in helper (reached via ``GFLOW_CLI_UI_MODE=agentic``) used to drive the
|
|
1062
1060
|
agentic path deterministically — the server-assigned A/B cohort has no
|
|
1063
1061
|
client-readable flag, but the in-composer "Agent" toggle switches the
|
|
1064
1062
|
classic composer into the same agentic layout (``crop_*`` → ``tune``).
|
|
@@ -2107,52 +2105,22 @@ class UiAutomationTransport(VideoGenerationMixin):
|
|
|
2107
2105
|
# of the editor before we click into settings / submit (#26).
|
|
2108
2106
|
await self._dismiss_blocking_overlays(page, out_dir)
|
|
2109
2107
|
|
|
2110
|
-
#
|
|
2111
|
-
#
|
|
2112
|
-
#
|
|
2113
|
-
#
|
|
2114
|
-
#
|
|
2115
|
-
#
|
|
2116
|
-
#
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
instruction_count=len(request.instructions),
|
|
2125
|
-
detail=(
|
|
2126
|
-
"Could not switch this session to the agentic composer; "
|
|
2127
|
-
"instruction cards (-i) may not be applied. This account "
|
|
2128
|
-
"may not offer Agent mode."
|
|
2129
|
-
),
|
|
2130
|
-
)
|
|
2131
|
-
|
|
2132
|
-
# Probe the DOM for the active UI cohort AFTER _enter_editor so the
|
|
2133
|
-
# project page is fully rendered. The cohort flaps per page load so
|
|
2134
|
-
# we re-probe every generation — never cache across calls.
|
|
2135
|
-
# Classic driver requires a transport reference for send_prompt.
|
|
2136
|
-
from gflow_cli.config import get_settings
|
|
2137
|
-
|
|
2138
|
-
ui_driver = await get_ui_driver(page, prefer_classic=get_settings().prefer_classic)
|
|
2108
|
+
# Determine the arm this command REQUIRES: explicit --ui-mode / env, or
|
|
2109
|
+
# inferred — agent instructions (-i) are an agentic-only surface, so they
|
|
2110
|
+
# force agentic. get_ui_driver switches to the required arm as a
|
|
2111
|
+
# PREREQUISITE, VERIFIES via a DOM re-probe, and fails fast
|
|
2112
|
+
# (UiModeUnavailableError, exit 28) if the arm is unreachable — so -i can
|
|
2113
|
+
# never silently no-op on a classic bind, and no credits are spent. The
|
|
2114
|
+
# cohort flaps per page load, so this runs every generation (no caching).
|
|
2115
|
+
from gflow_cli.config import infer_required_ui_mode, resolve_ui_mode
|
|
2116
|
+
|
|
2117
|
+
base_mode = request.ui_mode if request.ui_mode is not None else resolve_ui_mode(None)
|
|
2118
|
+
required_mode = infer_required_ui_mode(
|
|
2119
|
+
base_mode, has_instructions=bool(request.instructions)
|
|
2120
|
+
)
|
|
2121
|
+
ui_driver = await get_ui_driver(page, ui_mode=required_mode)
|
|
2139
2122
|
if ui_driver.name == "classic":
|
|
2140
2123
|
ui_driver._transport = self # type: ignore[union-attr]
|
|
2141
|
-
# Agent instruction cards are an agentic-only surface — the classic
|
|
2142
|
-
# driver has no brief to sync. Warn loudly (stderr) so ``-i`` never
|
|
2143
|
-
# silently no-ops: the user asked for instructions but this session
|
|
2144
|
-
# bound the classic cohort, so they will NOT be applied.
|
|
2145
|
-
if request.instructions:
|
|
2146
|
-
log.warning(
|
|
2147
|
-
"ui_automation.instructions_ignored_classic_cohort",
|
|
2148
|
-
instruction_count=len(request.instructions),
|
|
2149
|
-
detail=(
|
|
2150
|
-
"Custom agent instructions (-i) were provided but this Flow "
|
|
2151
|
-
"session is using the classic (non-agentic) UI, which has no "
|
|
2152
|
-
"instruction surface — they will be ignored for this generation. "
|
|
2153
|
-
"Instructions only apply on agentic-cohort sessions."
|
|
2154
|
-
),
|
|
2155
|
-
)
|
|
2156
2124
|
|
|
2157
2125
|
# Select Image mode explicitly. If the account was last in Video mode,
|
|
2158
2126
|
# an unguarded submission goes to the video endpoint and the image
|
|
@@ -2538,9 +2506,13 @@ class UiAutomationTransport(VideoGenerationMixin):
|
|
|
2538
2506
|
# cohort flaps per page load; bind once per batch (the editor stays
|
|
2539
2507
|
# mounted so the cohort is stable for this batch's lifetime).
|
|
2540
2508
|
# Classic driver requires a transport reference for send_prompt.
|
|
2541
|
-
|
|
2509
|
+
# No instruction inference here: the image-batch manifest carries no
|
|
2510
|
+
# per-item -i instructions (single-prompt only), so the required arm is
|
|
2511
|
+
# just the resolved --ui-mode / env. Route through infer_required_ui_mode
|
|
2512
|
+
# if batch ever gains instruction support.
|
|
2513
|
+
from gflow_cli.config import resolve_ui_mode
|
|
2542
2514
|
|
|
2543
|
-
ui_driver = await get_ui_driver(page,
|
|
2515
|
+
ui_driver = await get_ui_driver(page, ui_mode=resolve_ui_mode(None))
|
|
2544
2516
|
if ui_driver.name == "classic":
|
|
2545
2517
|
ui_driver._transport = self # type: ignore[union-attr]
|
|
2546
2518
|
|