gflow-cli 0.25.0__tar.gz → 0.27.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.25.0 → gflow_cli-0.27.0}/CHANGELOG.md +42 -1
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/PKG-INFO +1 -1
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/docs/INDEX.md +4 -1
- gflow_cli-0.27.0/docs/LIVE_VERIFICATION_v0.26.0.md +69 -0
- gflow_cli-0.27.0/docs/LIVE_VERIFICATION_v0.27.0.md +100 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/docs/MCP.md +1 -1
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/docs/MOVIE.md +70 -3
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/docs/PROJECT_STATUS.md +42 -1
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/docs/schemas/movie-handoff.schema.json +9 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/pyproject.toml +1 -1
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/__init__.py +1 -1
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/api/dto.py +35 -2
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/api/image.py +11 -2
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/api/transports/ui_automation.py +10 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/api/transports/ui_automation_video.py +115 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/cli_movie.py +57 -11
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/composition.py +80 -4
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/data/recorder.py +6 -1
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/mcp/tools.py +53 -11
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/movie_manifest.py +92 -4
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/worker/daemon.py +13 -1
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/api/test_image_dto.py +30 -0
- gflow_cli-0.27.0/tests/cli/test_movie_manifest_style_variants.py +455 -0
- gflow_cli-0.27.0/tests/composition/test_style_variants.py +272 -0
- gflow_cli-0.27.0/tests/composition/test_style_variants_e2e.py +305 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/mcp/test_tools_helpers.py +36 -5
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/mcp/test_tools_wired.py +1 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/worker/test_daemon.py +1 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/uv.lock +1 -1
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/.claude/README.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/.claude/commands/gflow/active.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/.claude/commands/gflow/branch-review.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/.claude/commands/gflow/changelog.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/.claude/commands/gflow/check.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/.claude/commands/gflow/doc-review.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/.claude/commands/gflow/issue-assessment.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/.claude/commands/gflow/issue-resolve.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/.claude/commands/gflow/known-issues.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/.claude/commands/gflow/next.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/.claude/commands/gflow/plan.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/.claude/commands/gflow/pr-council-review.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/.claude/commands/gflow/predict.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/.claude/commands/gflow/release.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/.claude/commands/gflow/scenario.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/.claude/commands/gflow/sonar.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/.claude/commands/gflow/status.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/.env.template +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/.gitattributes +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/.github/CODEOWNERS +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/.github/copilot-instructions.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/.github/dependabot.yml +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/.github/workflows/ci.yml +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/.github/workflows/external-pr-triage.yml +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/.github/workflows/governance-advisory.yml +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/.github/workflows/governance-benchmark.yml +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/.github/workflows/main-base-guard.yml +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/.github/workflows/release.yml +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/.gitignore +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/.gitleaks.toml +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/.pre-commit-config.yaml +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/.secrets.baseline +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/AGENTS.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/CLAUDE.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/CONFIGURATION.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/CONTRIBUTING.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/DISCLAIMER.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/GEMINI.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/KNOWN_ISSUES.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/LICENSE +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/PLAN.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/README.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/RELEASE.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/ROADMAP.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/conftest.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/docker-compose.yml +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/docs/AGENT_GUIDE.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/docs/AGENT_UI_E2E.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/docs/AGENT_UI_RECON.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/docs/ARCHITECTURE.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/docs/AUTHENTICATION.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/docs/CHARACTER.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/docs/CHARACTER_RECON.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/docs/CONFIGURATION.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/docs/DATA_LAYER.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/docs/DEBUGGING.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/docs/DEMOS.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/docs/DEVELOPMENT.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/docs/E2E_TESTING.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/docs/EXTERNAL_STORAGE.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/docs/GITHUB.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/docs/GOVERNANCE_BENCHMARK.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/docs/IMAGE_UPSCALE_RECON.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/docs/LIVE_VERIFICATION_data_layer.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/docs/LIVE_VERIFICATION_image_batch.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/docs/LIVE_VERIFICATION_v0.10.0.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/docs/LIVE_VERIFICATION_v0.11.0.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/docs/LIVE_VERIFICATION_v0.12.0.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/docs/LIVE_VERIFICATION_v0.13.0.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/docs/LIVE_VERIFICATION_v0.16.0.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/docs/LIVE_VERIFICATION_v0.17.0.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/docs/LIVE_VERIFICATION_v0.18.0.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/docs/LIVE_VERIFICATION_v0.19.0.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/docs/LIVE_VERIFICATION_v0.20.0.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/docs/LIVE_VERIFICATION_v0.20.1.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/docs/LIVE_VERIFICATION_v0.21.0.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/docs/LIVE_VERIFICATION_v0.22.0.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/docs/LIVE_VERIFICATION_v0.23.0.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/docs/LIVE_VERIFICATION_v0.24.0.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/docs/LIVE_VERIFICATION_v0.25.0.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/docs/LIVE_VERIFICATION_v0.7.0.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/docs/LIVE_VERIFICATION_v0.8.1.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/docs/LIVE_VERIFICATION_v0.9.0.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/docs/LIVE_VERIFICATION_v0.9.1.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/docs/LIVE_VERIFICATION_video_download.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/docs/PROMPT_EXPANSION.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/docs/SECURITY.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/docs/TOOLS.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/docs/USAGE.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/docs/USER_GUIDE.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/docs/assets/demo-split-pf.gif +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/docs/assets/example-run.gif +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/docs/assets/examples.webp +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/docs/medium_tutorial.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/docs/sonar-cleanup-tracker.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/docs/superpowers/plans/2026-06-12-issue-174-library-ui-attach/PLAN.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/docs/superpowers/plans/2026-06-22-mcp-server/PLAN.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/docs/superpowers/plans/2026-06-22-mcp-server/PREDICT.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/docs/superpowers/plans/2026-06-22-mcp-server/SCENARIO.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/docs/superpowers/plans/2026-06-22-prompt-expansion/PLAN.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/docs/superpowers/plans/2026-06-22-prompt-expansion/PREDICT.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/docs/superpowers/plans/2026-06-22-prompt-expansion/SCENARIO.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/docs/superpowers/plans/2026-06-24-gflow-studio-scaffold/PLAN.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/docs/superpowers/plans/2026-06-24-rest-api-layer/PLAN.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/docs/superpowers/plans/2026-06-26-mcp-e2e-test/PLAN.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/docs/superpowers/research/2026-06-27-tool-abstraction-evaluation.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/docs/superpowers/specs/2026-06-29-issue-assessment-workflow-design.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/examples/README.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/examples/batch_from_config.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/examples/multi_prompt_t2i.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/examples/sample_config.json +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/examples/sample_prompts.txt +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/examples/single_image_t2i.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/examples/workflow_chain.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/llms.txt +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/samples/README.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/samples/captured/01_upload_image.json +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/samples/captured/02_batchAsyncGenerateVideoText.json +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/samples/captured/03_batchCheckAsyncVideoGenerationStatus.json +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/samples/captured/04_archive_workflow.json +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/samples/captured/05_createProject.json +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/samples/captured/06_batchGenerateImages.json +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/samples/captured/07_batchGenerateImages_seeded.json +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/samples/captured/08_batchAsyncGenerateVideoStartAndEndImage.json +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/samples/captured/09_batchAsyncGenerateVideoReferenceImages.json +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/samples/captured/10_batchCheckAsyncVideoGenerationStatus_successful.json +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/samples/captured/11_batchCheckAsyncVideoGenerationStatus_failed.json +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/samples/captured/12_create_scene.json +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/samples/captured/13_sceneWorkflows_update.json +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/samples/captured/14_get_scene_workflows.json +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/samples/captured/15_commit_flowWorkflow.json +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/scripts/ci/check_doc_links.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/scripts/ci/check_materiality.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/scripts/ci/check_repo_hygiene.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/scripts/debug_editor.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/scripts/debug_gen_settings.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/scripts/debug_settings.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/scripts/dev/_recording_client.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/scripts/dev/_spike_common.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/scripts/dev/active_plan.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/scripts/dev/analyze_agent_ui_capture.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/scripts/dev/capture_i2v_frame_slots_dom.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/scripts/dev/capture_i2v_intercept_submit.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/scripts/dev/capture_i2v_model_select_repro.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/scripts/dev/capture_i2v_post_bind_state.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/scripts/dev/capture_image_add_media_dom.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/scripts/dev/capture_locale_invariants.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/scripts/dev/cdp_drive_and_probe.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/scripts/dev/character_create_spike.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/scripts/dev/character_create_spike_v2.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/scripts/dev/dump_character_selectors.js +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/scripts/dev/make_project.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/scripts/dev/materiality_backtest.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/scripts/dev/monitor_pr_38.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/scripts/dev/patch_character.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/scripts/dev/skillopt/README.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/scripts/dev/skillopt/harness.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/scripts/dev/skillopt/tasks.json +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/scripts/dev/spike_char_editor_dom.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/scripts/dev/spike_char_gen_capture.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/scripts/dev/spike_image_upscale_capture.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/scripts/dev/spike_image_upscale_drive.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/scripts/dev/spike_image_upscale_recaptcha_action.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/scripts/dev/spike_image_upscale_rest_probe.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/scripts/dev/spike_issue170_picker_locale_recon.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/scripts/dev/spike_issue174_library_ui_recon.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/scripts/dev/spike_movie_attach_payload.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/scripts/dev/spike_movie_entity_recon.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/scripts/dev/spike_movie_gen_capture.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/scripts/dev/spike_movie_picker_select.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/scripts/dev/spike_movie_voice_list.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/scripts/dev/spike_patch_entity.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/scripts/dev/spike_patchright.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/scripts/diag/README.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/scripts/diag/capture_flow_traffic.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/scripts/diag/memory_profile.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/scripts/diag/recaptcha_mint.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/scripts/e2e/agentic_image_e2e.ps1 +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/scripts/e2e/capture_agent_toggle.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/scripts/record_demo.ps1 +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/scripts/smoke_image.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/scripts/smoke_real_chrome_image.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/scripts/smoke_video_editor.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/scripts/smoke_worker_style.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/scripts/verify_chrome_auth_viability.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/skills/README.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/skills/gflow-cli/SKILL.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/skills/issue-assessment/SKILL.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/skills/issue-resolve/SKILL.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/skills/plan/SKILL.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/skills/pr-council-review/SKILL.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/skills/predict/SKILL.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/skills/scenario/SKILL.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/skills/status/SKILL.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/sonar-project.properties +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/__main__.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/_cli_helpers.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/api/__init__.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/api/_engine.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/api/_retry.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/api/_sapisidhash.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/api/character.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/api/client.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/api/image_upscale.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/api/recaptcha.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/api/routes.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/api/scene.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/api/transports/__init__.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/api/transports/_common.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/api/transports/_fingerprint.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/api/transports/base.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/api/transports/drivers/__init__.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/api/transports/drivers/agentic.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/api/transports/drivers/base.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/api/transports/drivers/classic.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/api/transports/drivers/factory.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/api/transports/experimental/__init__.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/api/transports/experimental/bearer.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/api/transports/experimental/evaluate_fetch.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/api/transports/experimental/sapisidhash.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/api/video.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/auth/__init__.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/auth/base.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/auth/cookies.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/auth/factory.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/auth/internal_chromium.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/auth/real_chrome.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/auth/strategies.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/auth/verification.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/browser_manager.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/chain.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/chain_manifest.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/cli.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/cli_character.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/cli_data.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/cli_image.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/cli_models.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/cli_run.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/cli_scene.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/cli_tools.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/cli_video.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/config.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/data/__init__.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/data/chain_repo.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/data/migrations/0001_initial.sql +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/data/migrations/0002_add_cloud_storage.sql +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/data/migrations/0003_add_scene_tables.sql +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/data/migrations/0004_add_scene_output_path.sql +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/data/migrations/0005_add_chain_links.sql +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/data/migrations/0006_add_operations_metadata.sql +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/data/migrations/0007_queue.sql +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/data/migrations/0008_add_operation_expanded_prompt.sql +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/data/migrations/__init__.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/data/models.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/data/queries.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/data/redaction.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/data/repository.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/data/store.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/errors.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/exceptions.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/image_batch.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/json_output.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/manifest.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/mcp/__init__.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/mcp/prompts.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/mcp/resources.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/mcp/server.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/media.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/observability.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/paths.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/profile_store.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/services/__init__.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/services/character_create.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/storage.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/tools/__init__.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/tools/banned.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/tools/builtin/__init__.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/tools/builtin/creative-director.toml +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/tools/expander.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/tools/invocation.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/tools/loader.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/tools/registry.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/tools/runtime.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/tools/spec.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/ui/app.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/ui/server.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/src/gflow_cli/worker/queue.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tasks/lessons.md +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/test_assets/sample_batch.json +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/test_assets/sample_batch.tsv +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/test_assets/sample_batch_invalid.tsv +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/__init__.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/api/__init__.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/api/fixtures/character_gen_response.json +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/api/fixtures/patch_entity_response.json +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/api/test_aisandbox_auth_error.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/api/test_aisandbox_auth_headers.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/api/test_bearer_redaction.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/api/test_character.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/api/test_client.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/api/test_client_character.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/api/test_client_delete_characters.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/api/test_client_generate_character.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/api/test_client_image.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/api/test_client_launch_kwargs.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/api/test_client_patch_entity.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/api/test_client_scene.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/api/test_client_upscale.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/api/test_concurrency.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/api/test_dto.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/api/test_engine.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/api/test_image.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/api/test_image_upscale.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/api/test_post_json_aisandbox_auth.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/api/test_recaptcha.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/api/test_retry.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/api/test_routes.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/api/test_routes_character.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/api/test_routes_scene.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/api/test_sapisidhash_helper.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/api/test_scene_models.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/api/test_video.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/api/test_video_request.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/api/transports/__init__.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/api/transports/conftest.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/api/transports/drivers/__init__.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/api/transports/drivers/test_agentic.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/api/transports/drivers/test_factory.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/api/transports/test_base.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/api/transports/test_bearer.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/api/transports/test_common.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/api/transports/test_evaluate_fetch.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/api/transports/test_factory.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/api/transports/test_fingerprint.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/api/transports/test_sapisidhash.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/api/transports/test_transport_timeout.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/api/transports/test_ui_automation.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/api/transports/test_ui_automation_batch.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/api/transports/test_ui_automation_image_mode.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/api/transports/test_ui_automation_video.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/api/transports/test_ui_character_editor.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/auth/strategies/test_factory.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/auth/strategies/test_strategies.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/auth/test_cookies.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/auth/test_verification.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/cli/__init__.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/cli/test_cli_auth_list.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/cli/test_cli_character.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/cli/test_cli_character_create.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/cli/test_cli_data.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/cli/test_cli_image.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/cli/test_cli_image_seed_removed.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/cli/test_cli_image_selector_drift.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/cli/test_cli_image_upscale.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/cli/test_cli_models.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/cli/test_cli_movie.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/cli/test_cli_run.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/cli/test_cli_scene.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/cli/test_cli_tools.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/cli/test_cli_video.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/cli/test_cli_video_chain.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/cli/test_error_handling.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/cli/test_helpers.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/cli/test_movie_manifest.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/cli/test_settings_validation.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/cli/test_t2i_multi_prompt.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/composition/test_character.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/composition/test_compose_prompt.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/composition/test_handoff.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/conftest.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/data/__init__.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/data/test_chain_repo.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/data/test_find_incomplete_character.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/data/test_models.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/data/test_packaging.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/data/test_recorder.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/data/test_recorder_character.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/data/test_redaction.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/data/test_repository.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/data/test_scene_persistence.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/data/test_settings_and_errors.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/data/test_store_migrations.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/dev/test_recording_client.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/e2e/__init__.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/e2e/conftest.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/e2e/test_aisandbox_auth_live.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/e2e/test_auth_verification_e2e.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/e2e/test_chain_e2e.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/e2e/test_character_create_e2e.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/e2e/test_daemon_e2e.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/e2e/test_data_layer_e2e.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/e2e/test_i2v_flags_e2e.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/e2e/test_image_batch_e2e.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/e2e/test_image_i2i_ref_cap_e2e.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/e2e/test_json_output_e2e.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/e2e/test_locale_selectors_e2e.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/e2e/test_scene_compose_live.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/e2e/test_tools_e2e.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/e2e/test_transports_e2e.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/e2e/test_video_r2v_ref_cap_e2e.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/e2e/test_video_t2v_e2e.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/features/__init__.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/features/auth.feature +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/features/auth_login.feature +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/features/character_create.feature +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/features/character_read.feature +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/features/conftest.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/features/image.feature +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/features/image_upscale.feature +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/features/locale_picker_include.feature +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/features/test_auth_login_steps.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/features/test_auth_steps.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/features/test_character_create_steps.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/features/test_character_read_steps.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/features/test_image_steps.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/features/test_image_upscale_steps.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/features/test_locale_picker_include_steps.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/features/test_step_collision_guard.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/features/test_video_agent_ui_steps.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/features/test_video_chain_steps.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/features/video_agent_ui.feature +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/features/video_chain.feature +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/fixtures/__init__.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/fixtures/seeded_catalog.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/image_batch/__init__.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/image_batch/test_image_manifest.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/image_batch/test_observability_events.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/integration/__init__.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/integration/conftest.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/integration/constants.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/integration/test_storage_gcs.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/integration/test_storage_s3.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/mcp/__init__.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/mcp/conftest.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/mcp/test_server.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/mcp/test_stdio_transport.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/scripts/test_analyze_agent_ui_capture.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/scripts/test_capture_locale_invariants.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/scripts/test_check_materiality.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/scripts/test_check_repo_hygiene.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/scripts/test_materiality_backtest.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/services/__init__.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/services/test_character_create_redaction.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/services/test_character_create_saga.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/services/test_character_gen_no_direct_post.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/smoke/__init__.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/smoke/test_profile_account_smoke.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/smoke/test_real_flow.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/test_auth.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/test_browser_manager.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/test_chain.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/test_chain_manifest.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/test_cli_data.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/test_config.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/test_conftest_isolation.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/test_data_queries.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/test_documentation_gate.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/test_errors.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/test_errors_403.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/test_json_output.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/test_manifest.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/test_marker_registry.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/test_media.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/test_observability.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/test_paths.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/test_profile_store.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/test_smoke.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/tools/__init__.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/tools/test_banned.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/tools/test_expander.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/tools/test_invocation.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/tools/test_loader.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/tools/test_registry.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/tools/test_runtime.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/tools/test_spec.py +0 -0
- {gflow_cli-0.25.0 → gflow_cli-0.27.0}/tests/ui/test_app.py +0 -0
|
@@ -7,6 +7,44 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.27.0] — 2026-07-07
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- **Global `[style]` block with named variants in `movie.toml` (Issue #239):** channel-format
|
|
15
|
+
videos can now express a visual style system (e.g. monochrome → warm color arc) once in the
|
|
16
|
+
`[style]` block and select it per-scene via `style_variant`, without repeating style text in
|
|
17
|
+
every scene's action. Adds `prefix`/`suffix` fields to `[style]`, `[style.variants.*]`
|
|
18
|
+
sub-tables, per-scene `style_variant` and `style_suffix` fields, deterministic composition
|
|
19
|
+
rule, and `style_applied` (variant/prefix/suffix/scene_suffix) per clip in the handoff
|
|
20
|
+
manifest. `none` is a reserved variant name (opt-out keyword) and may not be defined.
|
|
21
|
+
- **Prompt-aware resume for `movie run`:** completed scenes now persist a SHA-256 hash of
|
|
22
|
+
their composed prompt (`style_hash`); on resume, a scene whose prompt changed (style edit,
|
|
23
|
+
variant switch, action tweak) is regenerated instead of silently skipped. Unchanged scenes
|
|
24
|
+
still cost nothing. Old state files fall back to comparing the stored prompt text and are
|
|
25
|
+
never re-run on a guess. Dry-run shows the resolved style per scene and marks stale scenes
|
|
26
|
+
as `re-run (style changed)`.
|
|
27
|
+
|
|
28
|
+
## [0.26.0] — 2026-07-06
|
|
29
|
+
|
|
30
|
+
### Added
|
|
31
|
+
|
|
32
|
+
- **Reference a generated image in `image i2i` by its Flow UUID (`gflow_generate_image`,
|
|
33
|
+
`reference_images`)**: pass a generated image's media UUID as a reference and gflow
|
|
34
|
+
attaches it by **selecting the already-existing asset in Flow's reference picker** —
|
|
35
|
+
it does **not** upload a duplicate copy (avoiding duplication is the preferred path).
|
|
36
|
+
The asset's tile is located by its media id in the thumbnail URL (robust to
|
|
37
|
+
display-name collisions), surfaced by a display-name search when it isn't already
|
|
38
|
+
visible, and attached in place. When the asset can't be located (e.g. it's in a
|
|
39
|
+
different project's picker), gflow falls back to uploading its on-disk local file. A
|
|
40
|
+
UUID that isn't in your catalog still attaches by media id (no error). Live-verified:
|
|
41
|
+
a generated image's UUID → i2i output that references it, with no duplicate upload.
|
|
42
|
+
- **Generated images now record their Flow display name**: the display name is extracted
|
|
43
|
+
from the `batchGenerateImages` response's `workflows[]` array (previously ignored) and
|
|
44
|
+
persisted in the asset catalog — the searchable label the media picker shows, and what
|
|
45
|
+
the UUID-reference path searches by. (Original find and approach by **@C1ph3r404**,
|
|
46
|
+
#253/#255.)
|
|
47
|
+
|
|
10
48
|
## [0.25.0] — 2026-07-06
|
|
11
49
|
|
|
12
50
|
### Fixed
|
|
@@ -1792,7 +1830,10 @@ shell-script template that branches on these codes.
|
|
|
1792
1830
|
|
|
1793
1831
|
First skeleton. Not functional end-to-end yet.
|
|
1794
1832
|
|
|
1795
|
-
[Unreleased]: https://github.com/ffroliva/gflow-cli/compare/v0.
|
|
1833
|
+
[Unreleased]: https://github.com/ffroliva/gflow-cli/compare/v0.27.0...HEAD
|
|
1834
|
+
[0.27.0]: https://github.com/ffroliva/gflow-cli/compare/v0.26.0...v0.27.0
|
|
1835
|
+
[0.26.0]: https://github.com/ffroliva/gflow-cli/compare/v0.25.0...v0.26.0
|
|
1836
|
+
[0.25.0]: https://github.com/ffroliva/gflow-cli/compare/v0.24.0...v0.25.0
|
|
1796
1837
|
[0.24.0]: https://github.com/ffroliva/gflow-cli/compare/v0.23.0...v0.24.0
|
|
1797
1838
|
[0.23.0]: https://github.com/ffroliva/gflow-cli/compare/v0.22.0...v0.23.0
|
|
1798
1839
|
[0.22.0]: https://github.com/ffroliva/gflow-cli/compare/v0.21.0...v0.22.0
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: gflow-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.27.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
|
|
@@ -22,7 +22,10 @@ Welcome to the `gflow-cli` documentation. This index is the routing layer: it te
|
|
|
22
22
|
| [CONTRIBUTING](../CONTRIBUTING.md) | TDD workflow, test categories, coverage targets | Before opening a PR |
|
|
23
23
|
| **[docs/DEVELOPMENT.md](DEVELOPMENT.md)** | Branching model, PR protocol, e2e gate, version bump protocol, AI-assisted workflow | Understanding the end-to-end dev process |
|
|
24
24
|
| **[docs/E2E_TESTING.md](E2E_TESTING.md)** | Layer model, cost sub-markers, run commands, isolation patterns, roadmap to contract/replay layer | Running or extending e2e tests; cost control |
|
|
25
|
+
| **[docs/AGENT_UI_E2E.md](AGENT_UI_E2E.md)** | Deterministic e2e runbook for the Agentic UI image path (force-agent trigger, validation ledger) | Live-verifying Agentic-UI features |
|
|
25
26
|
| **[docs/GITHUB.md](GITHUB.md)** | Maintainer PR triage protocol, forked PR handling, SonarCloud scenarios | Reviewing or merging a GitHub PR |
|
|
27
|
+
| [docs/sonar-cleanup-tracker.md](sonar-cleanup-tracker.md) | SonarCloud zero-smells cleanup tracker (`chore/sonar-zero-cleanup`) | Resuming or auditing the Sonar cleanup effort |
|
|
28
|
+
| [docs/medium_tutorial.md](medium_tutorial.md) | Long-form tutorial article (Medium draft): Veo + Imagen from the terminal | Writing or updating outreach/tutorial content |
|
|
26
29
|
| [.env.template](../.env.template) | All environment variables with defaults | Setting up a new shell or container |
|
|
27
30
|
| **[docs/AUTHENTICATION.md](AUTHENTICATION.md)** | Full auth flow, session storage, multi-account, refresh | First `gflow auth login`, or auth errors |
|
|
28
31
|
| **[docs/CONFIGURATION.md](CONFIGURATION.md)** | All env vars, precedence chain, default paths per OS | Tuning behaviour, picking output paths |
|
|
@@ -117,7 +120,7 @@ Slash commands for Claude Code, stored in `.claude/commands/gflow/`. All prefixe
|
|
|
117
120
|
**"A gflow command hangs / fails — where do I start?"** → [DEBUGGING § Quick reference](DEBUGGING.md#quick-reference)
|
|
118
121
|
**"Flow's UI broke a selector — how do I diagnose it?"** → [DEBUGGING § Inspecting Flow's live UI](DEBUGGING.md#inspecting-flows-live-ui)
|
|
119
122
|
**"What does each `ui_automation.*` log event mean?"** → [DEBUGGING § Listener & HTTP-layer debugging](DEBUGGING.md#listener--http-layer-debugging)
|
|
120
|
-
**"What was actually live-verified for the latest release?"** → latest: [LIVE_VERIFICATION_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)
|
|
123
|
+
**"What was actually live-verified for the latest release?"** → latest: [LIVE_VERIFICATION_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)
|
|
121
124
|
**"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.
|
|
122
125
|
**"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)
|
|
123
126
|
**"What was live-verified for the video-download feature (#29)?"** → [LIVE_VERIFICATION_video_download](LIVE_VERIFICATION_video_download.md)
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# Live Verification — v0.26.0
|
|
2
|
+
|
|
3
|
+
Release date: 2026-07-06. Headline: **reference a generated image in `image i2i`
|
|
4
|
+
by its Flow UUID**, attached by **selecting the already-existing asset** in Flow's
|
|
5
|
+
reference picker rather than uploading a duplicate copy (the founder principle:
|
|
6
|
+
avoid duplication). Plus generated images now record their Flow **display name**
|
|
7
|
+
(the searchable picker label), extracted from the response's `workflows[]` array.
|
|
8
|
+
|
|
9
|
+
Live run: 2026-07-06, headed Playwright, profile `ffroliva`, real Flow.
|
|
10
|
+
|
|
11
|
+
## Scope
|
|
12
|
+
|
|
13
|
+
| Change | Surface | Verdict |
|
|
14
|
+
|---|---|---|
|
|
15
|
+
| Image i2i UUID ref → **select existing asset** (no duplicate) | `mcp/tools.py`, `worker/daemon.py`, `api/image.py`, `api/transports/ui_automation*.py` | ✅ **Live e2e GREEN** |
|
|
16
|
+
| Generated-image `display_name` from `workflows[]` | `api/dto.py`, `data/recorder.py` | ✅ Unit-tested (real captured sample); credited @C1ph3r404 |
|
|
17
|
+
|
|
18
|
+
## Mechanism
|
|
19
|
+
|
|
20
|
+
An `image i2i` `reference_images` entry that is a Flow media UUID is resolved at
|
|
21
|
+
enqueue time (best-effort, never errors — an uncatalogued UUID still attaches by
|
|
22
|
+
media id, PR #245) to the asset's `display_name` + on-disk `local_path`. The
|
|
23
|
+
transport then **prefers selecting the existing asset in place**:
|
|
24
|
+
|
|
25
|
+
1. Locate the tile by the **media UUID in its thumbnail URL** (`img[src*=<uuid>]`)
|
|
26
|
+
— robust to display-name collisions, needs no search term.
|
|
27
|
+
2. If not already visible, **search the display name** to surface it, then re-locate
|
|
28
|
+
by UUID.
|
|
29
|
+
3. Attach in place. (The image picker attaches on tile-click and auto-closes; the
|
|
30
|
+
code also handles the video-style explicit "Add to Prompt" include.)
|
|
31
|
+
4. **Fallback — local upload** only when the asset can't be located (e.g. it lives
|
|
32
|
+
in a different project's picker) and a local file exists.
|
|
33
|
+
|
|
34
|
+
## Live end-to-end result — GREEN
|
|
35
|
+
|
|
36
|
+
`gflow_generate_image(prompt="the same rustic workshop wall, wider shot, more
|
|
37
|
+
tools", reference_images=["60dcb880-…" (a generated image's UUID)],
|
|
38
|
+
project="0f4e7eaa-…" (the asset's project), profile="ffroliva")` via the real
|
|
39
|
+
stdio MCP server. 5-layer ledger:
|
|
40
|
+
|
|
41
|
+
1. **Attach path**: structlog `ui_automation_video.image_ref_selected_existing`
|
|
42
|
+
fired — and **no** `image_ref_upload_fallback` / `image_uploaded` event. The
|
|
43
|
+
existing asset was selected; **no duplicate was uploaded**.
|
|
44
|
+
2. **Wire**: the generation ran the `batchGenerateImages` route carrying the
|
|
45
|
+
reference `imageInput` — the ref reached the generation, not a plain t2i.
|
|
46
|
+
3. **File**: exactly one output written, `bee1e8a9-…_1.jpg`, 893 KB.
|
|
47
|
+
4. **Magic bytes**: `ff d8 ff e0` (valid JPEG); task `status: completed`.
|
|
48
|
+
5. **User-confirmable artifact**: the output shows the **same** rustic workshop
|
|
49
|
+
wall and the "v0.25.0" sign as the referenced image, as a wider shot with more
|
|
50
|
+
tools — the i2i reference visibly took.
|
|
51
|
+
|
|
52
|
+
### Pre-fix note
|
|
53
|
+
|
|
54
|
+
The first live attempt selected the asset correctly but errored looking for a
|
|
55
|
+
separate "Add to Prompt" button — the image picker attaches on tile-click and
|
|
56
|
+
auto-closes (one step), unlike the video r2v picker. Fixed to treat an
|
|
57
|
+
auto-closed dialog as success; the re-run above is GREEN. (A hung Chrome holding
|
|
58
|
+
the profile's `SingletonLock` also caused two transient `launch_persistent_context`
|
|
59
|
+
failures between runs — cleared by killing the process + removing the lock.)
|
|
60
|
+
|
|
61
|
+
## Automated coverage
|
|
62
|
+
|
|
63
|
+
- `_enrich_image_refs` unit tests (`tests/mcp/test_tools_helpers.py`): enriches a
|
|
64
|
+
catalogued ref with display_name + local_path; partial meta when no on-disk file;
|
|
65
|
+
uncatalogued UUID passes through with no error and no `ref_meta`.
|
|
66
|
+
- `display_name` extraction tests (`tests/api/test_image_dto.py`) against the real
|
|
67
|
+
captured `06_batchGenerateImages.json` sample.
|
|
68
|
+
- Full suite green (1994 passed; the one deselected `test_packaging` case is a
|
|
69
|
+
network-dependent sdist build, unrelated). `pyright src` 0 errors, ruff clean.
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# Live Verification — v0.27.0
|
|
2
|
+
|
|
3
|
+
Release date: 2026-07-07. Headline: **global `[style]` block with named variants
|
|
4
|
+
in `movie.toml`** (Issue #239, PR #259) — express a visual style arc once
|
|
5
|
+
(prefix/suffix + `[style.variants.*]`) and select it per-scene via
|
|
6
|
+
`style_variant` / `style_suffix` — plus **prompt-aware resume** for `movie run`
|
|
7
|
+
(completed scenes persist a `style_hash`; a scene whose composed prompt changed
|
|
8
|
+
is regenerated instead of silently skipped).
|
|
9
|
+
|
|
10
|
+
Verification run: 2026-07-07, real CLI (`gflow movie run --dry-run`), Windows,
|
|
11
|
+
`.venv` build of the release tree. **Deliberately credit-free**: this release is
|
|
12
|
+
pure local prompt composition + state logic — the Flow wire path (transports,
|
|
13
|
+
selectors, auth) is untouched, so no live Veo generation was spent. The dry-run
|
|
14
|
+
path exercises the identical manifest→parse→compose→resume-decision pipeline the
|
|
15
|
+
live run uses; only `_generate_scene` (unchanged this release) is skipped.
|
|
16
|
+
|
|
17
|
+
## Scope
|
|
18
|
+
|
|
19
|
+
| Change | Surface | Verdict |
|
|
20
|
+
|---|---|---|
|
|
21
|
+
| `[style]` prefix/suffix + `[style.variants.*]`, per-scene `style_variant`/`style_suffix` | `composition.py`, `movie_manifest.py` | ✅ CLI dry-run + 91 unit/integration tests |
|
|
22
|
+
| Prompt-aware resume (`style_hash`, `is_stale_for`, re-run on style edit) | `movie_manifest.py`, `cli_movie.py` | ✅ CLI dry-run 3-way ledger (below) |
|
|
23
|
+
| Dry-run shows resolved style + stale marker | `cli_movie.py` | ✅ CLI dry-run output |
|
|
24
|
+
| `style_applied` (variant/prefix/suffix/scene_suffix) per clip + schema | `composition.py`, `docs/schemas/movie-handoff.schema.json` | ✅ Unit-tested (jsonschema validation) |
|
|
25
|
+
| Reserved `none` variant name, strict variant parsing | `movie_manifest.py` | ✅ Unit-tested (ConfigurationError paths) |
|
|
26
|
+
|
|
27
|
+
## Evidence ledger (credit-free CLI runs)
|
|
28
|
+
|
|
29
|
+
Manifest: 3 scenes — `s1-base` (base style), `s2-warm` (`style_variant="warm"` +
|
|
30
|
+
`style_suffix="golden hour light"`), `s3-optout` (`style_variant="none"`), with
|
|
31
|
+
`prefix = "SCENE:"` and a base suffix.
|
|
32
|
+
|
|
33
|
+
1. **Composed prompt (canonical order)** — `compose_prompt` for `s1-base`
|
|
34
|
+
produced exactly:
|
|
35
|
+
`SCENE: Walks through a rainy plaza. Wide shot. Black and white cinematic
|
|
36
|
+
street photography, film grain.` — prefix first, sentence-composed
|
|
37
|
+
action/framing, raw base suffix last.
|
|
38
|
+
2. **Run 1 (fresh state)** — plan shows the resolved style per scene and full
|
|
39
|
+
cost: `s1-base … style=base 1 credit(s)`, `s2-warm … style=warm
|
|
40
|
+
+style_suffix 1 credit(s)`, `s3-optout … style=none 1 credit(s)`,
|
|
41
|
+
`Estimated credits: ~3`.
|
|
42
|
+
3. **Run 2 (s1 completed in `movie-state.json` with matching `style_hash`)** —
|
|
43
|
+
`s1-base … skip (done)`, `Estimated credits: ~2`. State file JSON carries
|
|
44
|
+
`"style_hash": "<sha256 of the composed prompt>"` (round-tripped via
|
|
45
|
+
`MovieState.save`/`load`).
|
|
46
|
+
4. **Run 3 (base suffix edited to "Sepia archival newsreel look.")** —
|
|
47
|
+
`s1-base … re-run (style changed) 1 credit(s)`, `Estimated credits: ~3`.
|
|
48
|
+
The stale scene is regenerated; the unchanged `s2-warm`/`s3-optout`
|
|
49
|
+
decisions are unaffected. This is the exact staleness bug the feature
|
|
50
|
+
exists to prevent (stale clip silently skipped after a style edit).
|
|
51
|
+
5. **User-confirmable artifact** — the three plan outputs above are
|
|
52
|
+
reproducible with any manifest; the same decision logic drives the real run
|
|
53
|
+
loop (`_run_movie` calls the identical `is_stale_for` check before spending
|
|
54
|
+
credits).
|
|
55
|
+
|
|
56
|
+
### Not live-verified this cycle (recorded, not omitted)
|
|
57
|
+
|
|
58
|
+
Actual Veo generation with a style-suffixed prompt (i.e. confirming Flow's
|
|
59
|
+
model renders the requested grade) was **not** exercised — it costs 20 credits
|
|
60
|
+
per scene and the prompt text demonstrably reaches the existing, unchanged
|
|
61
|
+
generation path (`_run_one_scene` passes the same `compose_prompt` output that
|
|
62
|
+
v0.26.0 passed). First credited `movie run` on a styled manifest will confirm
|
|
63
|
+
visually; no code path is untested locally.
|
|
64
|
+
|
|
65
|
+
### Pre-existing display nit (not this release)
|
|
66
|
+
|
|
67
|
+
The plan line's `[t2v]`/`[r2v]` mode tag is swallowed by rich markup
|
|
68
|
+
(`console.print` interprets `[t2v]` as a style tag) — present on `develop`
|
|
69
|
+
before PR #259; cosmetic; tracked as a follow-up.
|
|
70
|
+
|
|
71
|
+
## Pre-tag gates
|
|
72
|
+
|
|
73
|
+
- `/gflow:check`: hygiene ✅ · ruff ✅ (no rewrites) · pyright `0 errors` ✅ ·
|
|
74
|
+
full suite 2054 passed / 7 skipped ✅ (local), 3.11/3.12/3.13 matrix +
|
|
75
|
+
SonarCloud quality gate ✅ on PR #259 (same tree).
|
|
76
|
+
- `/code-review` (independent, 8-angle): 10 findings — all fixed in
|
|
77
|
+
`61a9887` before merge.
|
|
78
|
+
- `/gflow:doc-review`: mechanical pass UPDATED×2 (PROJECT_STATUS current
|
|
79
|
+
release was stale at v0.24.0 — v0.25.0/v0.26.0/v0.27.0 entries added; 3 docs
|
|
80
|
+
added to INDEX), links 23/23 green. Council verdict: **GREEN/YELLOW/YELLOW**
|
|
81
|
+
across 3 auditors — 1 Tier-1 finding (this doc overclaimed "91
|
|
82
|
+
style-variants tests"; actual collection is 59 — fixed in the release-prep
|
|
83
|
+
commit), Tier-2 fixed (stale MOVIE.md "active development" banner), Tier-3
|
|
84
|
+
deferred (hardcoded `build_handoff` `generator.version="0.14.0"`; MOVIE.md
|
|
85
|
+
error-path doc anchor; USAGE.md movie coverage). Council reports at
|
|
86
|
+
`tmp/council/0{1,2,3}-*.md` (local-only).
|
|
87
|
+
|
|
88
|
+
## Post-tag evidence
|
|
89
|
+
|
|
90
|
+
*(filled after the v0.27.0 tag push / publish)*
|
|
91
|
+
|
|
92
|
+
## Automated coverage
|
|
93
|
+
|
|
94
|
+
- 59 style-variants tests across `tests/composition/test_style_variants.py`,
|
|
95
|
+
`test_style_variants_e2e.py`, `tests/cli/test_movie_manifest_style_variants.py`
|
|
96
|
+
(composition order, variant resolution, reserved `none`, strict parsing,
|
|
97
|
+
`style_applied` + jsonschema validation, `resume_hash` properties,
|
|
98
|
+
`is_stale_for` all four branches, state round-trip).
|
|
99
|
+
- Full suite green: 2054 passed, 7 skipped (local) and 3.11/3.12/3.13 matrix +
|
|
100
|
+
SonarCloud quality gate green on PR #259. `pyright src` 0 errors, ruff clean.
|
|
@@ -45,7 +45,7 @@ Both Click CLI (`src/gflow_cli/cli.py`) and MCP Server (`src/gflow_cli/mcp/`) ar
|
|
|
45
45
|
The server registers three protocol surfaces:
|
|
46
46
|
|
|
47
47
|
### Tools (Executable actions)
|
|
48
|
-
* `gflow_generate_image(prompt, model, aspect, count, seed, reference_images, tools, profile, project)`: Triggers text-to-image / image-to-image (Imagen / Nano Banana). `reference_images` switches to i2i; `project` generates into an existing Flow project id (mirrors CLI `--project`).
|
|
48
|
+
* `gflow_generate_image(prompt, model, aspect, count, seed, reference_images, tools, profile, project)`: Triggers text-to-image / image-to-image (Imagen / Nano Banana). `reference_images` switches to i2i and accepts **either a local file path or a generated image's Flow media UUID**. A UUID reference is attached by **selecting the already-existing asset in Flow's reference picker — no duplicate copy is uploaded** (locating the tile by the media id in its thumbnail URL, and searching the recorded display name to surface it when needed); gflow falls back to uploading the asset's on-disk local file only when it can't be located in place (e.g. it lives in a different project's picker). `project` generates into an existing Flow project id (mirrors CLI `--project`) — pass the reference's project to keep it selectable in place.
|
|
49
49
|
* `gflow_generate_video(prompt, mode, aspect, initial_frame, end_frame, reference_images, tools, profile, project)`: Triggers vertical or landscape video generation (Veo). `mode` is `t2v`/`i2v`/`r2v`; `i2v` requires `initial_frame`, `r2v` requires `reference_images`; `project` generates into an existing Flow project id (mirrors CLI `--project`). `initial_frame`, `end_frame`, and `reference_images` each accept **either a local file path or the Flow image UUID of a generated asset** — pass a generated image's id straight in to chain image→video, and gflow attaches it for you (the UUID is resolved to the asset's already-on-disk local file and uploaded as the frame; no manual download/re-upload step). A UUID that isn't in your local asset catalog is rejected up front with a clear "Reference Not Found" error; a catalogued asset whose local file is no longer on disk gives a "Reference Not On Disk" error (re-generate it or pass a local path).
|
|
50
50
|
* `gflow_list_projects(profile, limit)`: Queries SQLite catalog for recent generation folders.
|
|
51
51
|
* `gflow_list_characters(profile)`: Lists Flow Character entities (requires an active browser session).
|
|
@@ -5,9 +5,9 @@ clips that share the **same characters** (face + voice) across every scene. It
|
|
|
5
5
|
is the orchestration layer on top of `gflow character` (entity creation) and
|
|
6
6
|
`gflow video` (R2V generation).
|
|
7
7
|
|
|
8
|
-
> Status:
|
|
9
|
-
>
|
|
10
|
-
>
|
|
8
|
+
> Status: shipped (since v0.14.0) and evolving. The CLI surface below is
|
|
9
|
+
> release-stable per SemVer; alpha (`0.x`) minor versions may still extend or
|
|
10
|
+
> adjust it, with changes noted in the CHANGELOG.
|
|
11
11
|
|
|
12
12
|
## Quick start
|
|
13
13
|
|
|
@@ -31,6 +31,18 @@ title = "E2E Stickman"
|
|
|
31
31
|
project = "6ba50219-…" # reusable Flow project id
|
|
32
32
|
output_dir = "./out"
|
|
33
33
|
|
|
34
|
+
[style]
|
|
35
|
+
look = "cinematic, shallow depth of field"
|
|
36
|
+
palette = "warm golden tones"
|
|
37
|
+
negative = "no text, no watermark"
|
|
38
|
+
suffix = "Black and white cinematic street photography, photorealistic, film grain."
|
|
39
|
+
|
|
40
|
+
[style.variants.warm]
|
|
41
|
+
suffix = "Warm golden-hour cinematic grade."
|
|
42
|
+
|
|
43
|
+
[style.variants.cool]
|
|
44
|
+
suffix = "Cool blue-toned cinematic grade."
|
|
45
|
+
|
|
34
46
|
[[characters]]
|
|
35
47
|
name = "Stickman"
|
|
36
48
|
identity = "entity" # reuse a Flow CHARACTER entity across scenes
|
|
@@ -47,6 +59,14 @@ line = "We finally made it to the top!"
|
|
|
47
59
|
aspect = "9:16"
|
|
48
60
|
model = "veo-lite"
|
|
49
61
|
duration = 8
|
|
62
|
+
|
|
63
|
+
[[scenes]]
|
|
64
|
+
id = "close-up"
|
|
65
|
+
action = "smiles with excitement"
|
|
66
|
+
style_variant = "warm" # selects [style.variants.warm]
|
|
67
|
+
style_suffix = "golden hour light" # appended after the variant suffix
|
|
68
|
+
aspect = "9:16"
|
|
69
|
+
duration = 6
|
|
50
70
|
```
|
|
51
71
|
|
|
52
72
|
On first run, characters with `identity = "entity"` are created once (image
|
|
@@ -54,6 +74,53 @@ generation — **free**, no credits) and cached. Each scene then generates a cli
|
|
|
54
74
|
that **reuses the same Flow CHARACTER entity** so the character drives every
|
|
55
75
|
scene from one identity.
|
|
56
76
|
|
|
77
|
+
### Style variants
|
|
78
|
+
|
|
79
|
+
The `[style]` block defines a **global visual style** applied to every scene.
|
|
80
|
+
For channel-format videos where the style changes across scenes (e.g. a
|
|
81
|
+
monochrome → warm color arc), use **named variants**:
|
|
82
|
+
|
|
83
|
+
```toml
|
|
84
|
+
[style]
|
|
85
|
+
prefix = "" # optional, prepended before the composed scene text
|
|
86
|
+
suffix = "Black and white cinematic street photography, photorealistic, film grain."
|
|
87
|
+
|
|
88
|
+
[style.variants.warm]
|
|
89
|
+
suffix = "Warm golden-hour cinematic grade."
|
|
90
|
+
|
|
91
|
+
[style.variants.cool]
|
|
92
|
+
suffix = "Cool blue-toned cinematic grade."
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Per-scene selection:
|
|
96
|
+
|
|
97
|
+
| Field | Effect |
|
|
98
|
+
|---|---|
|
|
99
|
+
| `style_variant = "warm"` | Selects `[style.variants.warm]` — its `suffix` replaces the base `suffix`. |
|
|
100
|
+
| `style_variant = "none"` | Opts out of all style suffixes (base + variant). Prefix is still applied. |
|
|
101
|
+
| *(omitted)* | Uses the base `[style]` suffix. |
|
|
102
|
+
| `style_suffix = "sunset light"` | Scene-specific text appended **after** the variant/base suffix. |
|
|
103
|
+
|
|
104
|
+
`none` is a **reserved name**: defining `[style.variants.none]` is a
|
|
105
|
+
configuration error, so the opt-out keyword can never shadow a real variant.
|
|
106
|
+
|
|
107
|
+
**Composition rule** (deterministic, no LLM):
|
|
108
|
+
|
|
109
|
+
```
|
|
110
|
+
final_prompt = [prefix] + composed_scene_text + [variant.suffix | base.suffix] + [scene.style_suffix]
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
The applied style is recorded per clip in `<manifest>-handoff.json` as
|
|
114
|
+
`style_applied` (`variant`, `prefix`, `suffix`, `scene_suffix`), so downstream
|
|
115
|
+
tools (Remotion, editors) can introspect it.
|
|
116
|
+
|
|
117
|
+
**Resume:** each completed scene's state records a hash of its composed
|
|
118
|
+
prompt. If you edit the style (or anything else that changes a scene's
|
|
119
|
+
prompt) and re-run, only the affected scenes are regenerated — unchanged
|
|
120
|
+
scenes are still skipped and cost no credits. State files written by older
|
|
121
|
+
gflow-cli versions fall back to comparing the stored prompt text; scenes with
|
|
122
|
+
no stored prompt are never re-run automatically.
|
|
123
|
+
|
|
57
124
|
> **Consistency is best-effort, not pixel-exact.** gflow guarantees the *right
|
|
58
125
|
> entity rides the wire* (`consistency_method = entity`); the final on-screen
|
|
59
126
|
> fidelity is Flow's Veo R2V model, which may reinterpret minimalist or
|
|
@@ -4,6 +4,43 @@
|
|
|
4
4
|
|
|
5
5
|
## Current release
|
|
6
6
|
|
|
7
|
+
**v0.27.0 — alpha.** **Global `[style]` block with named variants + prompt-aware resume
|
|
8
|
+
for `gflow movie` (#239).** A `movie.toml` can now express a visual style system once —
|
|
9
|
+
`prefix`/`suffix` on `[style]` plus `[style.variants.*]` sub-tables — and select it
|
|
10
|
+
per-scene via `style_variant` / `style_suffix` (deterministic composition, `none`
|
|
11
|
+
reserved as the opt-out keyword). The handoff manifest records `style_applied`
|
|
12
|
+
(variant/prefix/suffix/scene_suffix) per clip. Resume is now prompt-aware: completed
|
|
13
|
+
scenes persist a `style_hash`; a scene whose composed prompt changed is regenerated
|
|
14
|
+
instead of silently skipped, and dry-run marks it `re-run (style changed)`. Carries
|
|
15
|
+
forward v0.26.0 (i2i select-in-place by UUID). Verification:
|
|
16
|
+
[LIVE_VERIFICATION_v0.27.0](LIVE_VERIFICATION_v0.27.0.md) (credit-free CLI ledger).
|
|
17
|
+
|
|
18
|
+
**Develop (unreleased, post-v0.27.0):** *(empty — develop is the staging branch for the next release).*
|
|
19
|
+
|
|
20
|
+
<details><summary>v0.26.0 — image i2i references a generated image by UUID (select in place)</summary>
|
|
21
|
+
|
|
22
|
+
**v0.26.0 — alpha.** **Reference a generated image in `image i2i` by its Flow UUID.**
|
|
23
|
+
A `reference_images` entry that is a media UUID is attached by **selecting the
|
|
24
|
+
already-existing asset in Flow's reference picker** (located by UUID in the thumbnail
|
|
25
|
+
URL, surfaced by display-name search when hidden) — no duplicate upload; local upload
|
|
26
|
+
remains the fallback. Generated images also record their Flow `display_name` (credited
|
|
27
|
+
@C1ph3r404). Verification: [LIVE_VERIFICATION_v0.26.0](LIVE_VERIFICATION_v0.26.0.md)
|
|
28
|
+
(live e2e GREEN).
|
|
29
|
+
|
|
30
|
+
</details>
|
|
31
|
+
|
|
32
|
+
<details><summary>v0.25.0 — remote-UUID i2v + silent-failure guards</summary>
|
|
33
|
+
|
|
34
|
+
**v0.25.0 — alpha.** **`video i2v` from a generated image's UUID proven live (#237)** —
|
|
35
|
+
the picker-search attach was reworked to a local-upload path, producing a real 8s
|
|
36
|
+
interpolation from a catalogued UUID. Home-`.env` config matrix (#240) verified live.
|
|
37
|
+
Two silent failures made loud: video-as-image download rejection and rejected-upload
|
|
38
|
+
fail-fast. Verification: [LIVE_VERIFICATION_v0.25.0](LIVE_VERIFICATION_v0.25.0.md).
|
|
39
|
+
|
|
40
|
+
</details>
|
|
41
|
+
|
|
42
|
+
<details><summary>v0.24.0 — `--project` parity across CLI + MCP</summary>
|
|
43
|
+
|
|
7
44
|
**v0.24.0 — alpha.** **`--project` parity across CLI + MCP.** The video commands
|
|
8
45
|
(`video t2v`/`i2v`/`r2v`) gain `--project <id>` to generate into an existing Flow project
|
|
9
46
|
instead of a scratch one (#233/#234), matching `image t2i`/`i2i`; and the MCP
|
|
@@ -13,7 +50,7 @@ capability (`payload["project_id"]`) and validate the id identically. Carries fo
|
|
|
13
50
|
v0.23.0 (MCP generation live + macOS 401 fix). Verification:
|
|
14
51
|
[LIVE_VERIFICATION_v0.24.0](LIVE_VERIFICATION_v0.24.0.md).
|
|
15
52
|
|
|
16
|
-
|
|
53
|
+
</details>
|
|
17
54
|
|
|
18
55
|
<details><summary>v0.23.0 — MCP generation live + macOS 401 fixed</summary>
|
|
19
56
|
|
|
@@ -99,6 +136,10 @@ reporter-verified e2e on macOS).
|
|
|
99
136
|
| Tools framework: `gflow tools` group + `--tool` + `creative-director` + "My Tools" + MCP parity | ✅ done (v0.22.0) |
|
|
100
137
|
| MCP generation wired to FlowWorker (tool→queue→download→record) + `tools` applied + i2v/r2v boundary validation | ✅ done (v0.23.0) |
|
|
101
138
|
| macOS generation 401 fixed — `/fx` cookie-path read + headed-context seed (#222/#230) | ✅ done (v0.23.0) |
|
|
139
|
+
| `--project <id>` on `video t2v/i2v/r2v` + MCP `project` parameter (#233/#234/#235) | ✅ done (v0.24.0) |
|
|
140
|
+
| `video i2v` from a generated image's UUID (#237) + home-`.env` matrix (#240) + silent-failure guards | ✅ done (v0.25.0) |
|
|
141
|
+
| `image i2i` references a generated image by UUID — select in place, no duplicate upload + `display_name` capture | ✅ done (v0.26.0) |
|
|
142
|
+
| `movie.toml` `[style]` block with named variants + prompt-aware resume (`style_hash`) (#239) | ✅ done (v0.27.0) |
|
|
102
143
|
| `gflow video batch` (TSV manifest) on `ui_automation` | ⏳ Phase B |
|
|
103
144
|
| Persistence layer (stay-mounted batch sessions across project boundaries) | ⏳ Phase B |
|
|
104
145
|
| Provider abstraction for official Veo 3.1 API | ⏳ planned |
|
|
@@ -50,6 +50,15 @@
|
|
|
50
50
|
"dialogue": { "type": "array" },
|
|
51
51
|
"prompt": { "type": ["string", "null"] },
|
|
52
52
|
"status": { "enum": ["completed", "failed"] },
|
|
53
|
+
"style_applied": {
|
|
54
|
+
"type": "object",
|
|
55
|
+
"properties": {
|
|
56
|
+
"variant": { "type": ["string", "null"] },
|
|
57
|
+
"prefix": { "type": ["string", "null"] },
|
|
58
|
+
"suffix": { "type": ["string", "null"] },
|
|
59
|
+
"scene_suffix": { "type": ["string", "null"] }
|
|
60
|
+
}
|
|
61
|
+
},
|
|
53
62
|
"x_gflow": { "type": "object" }
|
|
54
63
|
}
|
|
55
64
|
}
|
|
@@ -8,7 +8,7 @@ KeyErrors leak.
|
|
|
8
8
|
|
|
9
9
|
from __future__ import annotations
|
|
10
10
|
|
|
11
|
-
from dataclasses import dataclass
|
|
11
|
+
from dataclasses import dataclass, replace
|
|
12
12
|
from typing import TYPE_CHECKING, Any, Literal, cast
|
|
13
13
|
|
|
14
14
|
if TYPE_CHECKING:
|
|
@@ -128,6 +128,10 @@ class GeneratedImage:
|
|
|
128
128
|
fife_url: str # CDN URL — usually expires after ~6 hours
|
|
129
129
|
dimensions: tuple[int, int] # (width, height)
|
|
130
130
|
media_generation_id: str | None = None
|
|
131
|
+
# Flow-assigned display name (from the response's `workflows[]` array). This
|
|
132
|
+
# is the searchable label the media picker shows — recorded so a generated
|
|
133
|
+
# image can be referenced by name later. Original find by @C1ph3r404 (#253).
|
|
134
|
+
display_name: str | None = None
|
|
131
135
|
|
|
132
136
|
@property
|
|
133
137
|
def is_signed_url(self) -> bool:
|
|
@@ -172,8 +176,37 @@ class GeneratedImage:
|
|
|
172
176
|
if not isinstance(media, list):
|
|
173
177
|
msg = "unexpected batchGenerateImages response shape: media is not a list"
|
|
174
178
|
raise ValueError(msg)
|
|
179
|
+
# Flow returns display names in a sibling `workflows[]` array keyed by
|
|
180
|
+
# workflow id (mirrors AssetInfo.from_upload_response). Build the lookup
|
|
181
|
+
# once and inject the name onto each parsed image. (Find by @C1ph3r404.)
|
|
182
|
+
workflow_names = cls._workflow_display_names(data.get("workflows"))
|
|
175
183
|
items = cast("list[dict[str, Any]]", media)
|
|
176
|
-
|
|
184
|
+
results: list[GeneratedImage] = []
|
|
185
|
+
for item in items:
|
|
186
|
+
img = cls.from_response_item(item)
|
|
187
|
+
name = workflow_names.get(img.workflow_id)
|
|
188
|
+
if name:
|
|
189
|
+
img = replace(img, display_name=name)
|
|
190
|
+
results.append(img)
|
|
191
|
+
return results
|
|
192
|
+
|
|
193
|
+
@staticmethod
|
|
194
|
+
def _workflow_display_names(workflows: object) -> dict[str, str]:
|
|
195
|
+
"""Map workflow id → displayName from the response's ``workflows[]``."""
|
|
196
|
+
names: dict[str, str] = {}
|
|
197
|
+
if not isinstance(workflows, list):
|
|
198
|
+
return names
|
|
199
|
+
for w in cast("list[Any]", workflows):
|
|
200
|
+
if not isinstance(w, dict):
|
|
201
|
+
continue
|
|
202
|
+
entry = cast("dict[str, Any]", w)
|
|
203
|
+
w_id = entry.get("name")
|
|
204
|
+
metadata = entry.get("metadata")
|
|
205
|
+
if isinstance(w_id, str) and isinstance(metadata, dict):
|
|
206
|
+
display_name = cast("dict[str, Any]", metadata).get("displayName")
|
|
207
|
+
if isinstance(display_name, str) and display_name:
|
|
208
|
+
names[w_id] = display_name
|
|
209
|
+
return names
|
|
177
210
|
|
|
178
211
|
|
|
179
212
|
@dataclass(frozen=True)
|
|
@@ -185,11 +185,20 @@ class ImageRef:
|
|
|
185
185
|
"""A reference image for I2I, identified by the upload's media UUID.
|
|
186
186
|
|
|
187
187
|
The wire shape is the dict returned by :meth:`to_wire`. The UUID comes
|
|
188
|
-
from a prior ``/v1/flow/uploadImage`` call
|
|
189
|
-
``samples/captured/01_upload_image.json``).
|
|
188
|
+
from a prior ``/v1/flow/uploadImage`` call OR a generated image's media id
|
|
189
|
+
(see ``samples/captured/01_upload_image.json``).
|
|
190
|
+
|
|
191
|
+
``display_name`` and ``local_path`` are UI-automation-only hints (ignored by
|
|
192
|
+
:meth:`to_wire`): they let the transport attach the ref by **selecting the
|
|
193
|
+
already-existing Flow asset in the picker** — located by ``name`` (the media
|
|
194
|
+
UUID) in the tile's image URL, surfaced by ``display_name`` when a search is
|
|
195
|
+
needed — and preferred over re-uploading a duplicate. ``local_path`` is the
|
|
196
|
+
fallback file to upload only when the asset can't be located in place.
|
|
190
197
|
"""
|
|
191
198
|
|
|
192
199
|
name: str
|
|
200
|
+
display_name: str = ""
|
|
201
|
+
local_path: str = ""
|
|
193
202
|
|
|
194
203
|
def __post_init__(self) -> None:
|
|
195
204
|
# Reject empty, whitespace-only, AND whitespace-padded UUIDs.
|
|
@@ -2110,6 +2110,16 @@ class UiAutomationTransport(VideoGenerationMixin):
|
|
|
2110
2110
|
if request.ref_paths:
|
|
2111
2111
|
await self._attach_references(page, list(request.ref_paths), out_dir=out_dir)
|
|
2112
2112
|
|
|
2113
|
+
# Pre-generated image UUID refs: attach by selecting the EXISTING Flow
|
|
2114
|
+
# asset in the reference picker (no duplicate upload — founder principle),
|
|
2115
|
+
# falling back to uploading the local file only when it can't be located.
|
|
2116
|
+
if request.refs:
|
|
2117
|
+
await self._attach_image_uuid_refs(
|
|
2118
|
+
page,
|
|
2119
|
+
[(r.name, r.display_name, r.local_path) for r in request.refs],
|
|
2120
|
+
out_dir=out_dir,
|
|
2121
|
+
)
|
|
2122
|
+
|
|
2113
2123
|
# Entity references: attach locked CHARACTER entities via the Personagens
|
|
2114
2124
|
# picker (inherited from the video transport). The entity must live in the
|
|
2115
2125
|
# project we generate in (pass --project / project_id). Flow's JS then
|