gflow-cli 0.40.0__tar.gz → 0.41.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.41.0/.claude/commands/gflow/live-verify.md +9 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/.env.template +12 -8
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/.github/workflows/ci.yml +31 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/.github/workflows/main-base-guard.yml +1 -1
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/.github/workflows/pages.yml +4 -4
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/.gitignore +0 -4
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/AGENTS.md +5 -3
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/CHANGELOG.md +61 -1
- gflow_cli-0.41.0/CONFIGURATION.md +39 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/KNOWN_ISSUES.md +52 -37
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/PKG-INFO +4 -4
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/PLAN.md +2 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/README.md +2 -2
- {gflow_cli-0.40.0/website → gflow_cli-0.41.0}/docs/ARCHITECTURE.md +2 -2
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/AUTHENTICATION.md +11 -8
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/CONFIGURATION.md +8 -8
- {gflow_cli-0.40.0/website → gflow_cli-0.41.0}/docs/E2E_TESTING.md +7 -2
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/INDEX.md +4 -2
- gflow_cli-0.41.0/docs/LIVE_VERIFICATION_v0.40.0-production-readiness.md +376 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/LIVE_VERIFICATION_v0.40.0.md +5 -3
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/PROJECT_STATUS.md +8 -2
- {gflow_cli-0.40.0/website → gflow_cli-0.41.0}/docs/USAGE.md +22 -24
- {gflow_cli-0.40.0/website → gflow_cli-0.41.0}/docs/USER_GUIDE.md +85 -67
- gflow_cli-0.41.0/docs/superpowers/plans/2026-07-19-live-verify/PLAN.md +446 -0
- gflow_cli-0.41.0/docs/superpowers/plans/2026-07-19-production-readiness-browser-lifecycle.md +189 -0
- gflow_cli-0.41.0/docs/superpowers/plans/2026-07-19-production-readiness-driver-cdp-verification.md +159 -0
- gflow_cli-0.41.0/docs/superpowers/plans/2026-07-19-production-readiness-public-truth.md +178 -0
- gflow_cli-0.41.0/docs/superpowers/plans/2026-07-19-production-readiness-queue-safety.md +213 -0
- gflow_cli-0.41.0/docs/superpowers/specs/2026-07-19-live-verify-design.md +223 -0
- gflow_cli-0.41.0/docs/superpowers/specs/2026-07-19-production-readiness-hardening-design.md +433 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/pyproject.toml +3 -3
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/skills/check/SKILL.md +3 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/skills/gflow-cli/SKILL.md +14 -10
- gflow_cli-0.41.0/skills/live-verify/SKILL.md +145 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/__init__.py +1 -1
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/api/_engine.py +50 -1
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/api/client.py +159 -41
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/api/dto.py +30 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/api/transports/base.py +33 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/api/transports/drivers/agentic.py +68 -32
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/api/transports/drivers/base.py +23 -17
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/api/transports/drivers/classic.py +23 -41
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/api/transports/drivers/factory.py +10 -2
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/api/transports/experimental/bearer.py +4 -1
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/api/transports/experimental/evaluate_fetch.py +13 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/api/transports/experimental/sapisidhash.py +4 -1
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/api/transports/ui_automation.py +131 -41
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/auth/cookies.py +6 -1
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/auth/internal_chromium.py +5 -1
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/auth/real_chrome.py +51 -20
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/auth/verification.py +6 -1
- gflow_cli-0.41.0/src/gflow_cli/browser_manager.py +262 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/chain_manifest.py +1 -3
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/cli_video.py +0 -24
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/data/chain_repo.py +8 -2
- gflow_cli-0.41.0/src/gflow_cli/data/migrations/0009_queue_claims.sql +44 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/data/recorder.py +13 -2
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/errors.py +65 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/mcp/tools.py +178 -173
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/paths.py +10 -0
- gflow_cli-0.41.0/src/gflow_cli/profile_lease.py +254 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/services/mentions.py +23 -5
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/ui/app.py +35 -33
- gflow_cli-0.41.0/src/gflow_cli/worker/codec.py +275 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/worker/daemon.py +127 -151
- gflow_cli-0.41.0/src/gflow_cli/worker/queue.py +414 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/api/test_client.py +252 -21
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/api/transports/drivers/test_agentic.py +96 -21
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/api/transports/drivers/test_classic.py +8 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/api/transports/test_bearer.py +66 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/api/transports/test_evaluate_fetch.py +60 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/api/transports/test_sapisidhash.py +62 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/api/transports/test_ui_automation.py +82 -1
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/api/transports/test_ui_automation_batch.py +3 -1
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/auth/strategies/test_strategies.py +100 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/auth/test_cookies.py +54 -0
- gflow_cli-0.41.0/tests/auth/test_real_chrome.py +145 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/auth/test_verification.py +38 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/cli/test_cli_video.py +45 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/cli/test_error_handling.py +4 -13
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/data/test_chain_repo.py +30 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/data/test_recorder.py +25 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/data/test_store_migrations.py +1 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/e2e/test_daemon_e2e.py +57 -28
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/features/test_video_agent_ui_steps.py +8 -1
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/mcp/test_cli_parity.py +0 -1
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/services/test_mentions_resolve.py +55 -1
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/services/test_resolve_and_apply.py +22 -0
- gflow_cli-0.41.0/tests/test_browser_manager.py +235 -0
- gflow_cli-0.41.0/tests/test_documentation_gate.py +92 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/test_errors.py +22 -0
- gflow_cli-0.41.0/tests/test_profile_lease.py +148 -0
- gflow_cli-0.41.0/tests/test_profile_lease_subprocess.py +216 -0
- gflow_cli-0.41.0/tests/ui/test_app.py +202 -0
- gflow_cli-0.41.0/tests/worker/test_codec.py +117 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/worker/test_daemon.py +13 -11
- gflow_cli-0.41.0/tests/worker/test_mcp_daemon_race.py +116 -0
- gflow_cli-0.41.0/tests/worker/test_queue.py +173 -0
- gflow_cli-0.41.0/tests/worker/test_queue_multiprocess.py +80 -0
- gflow_cli-0.41.0/tests/worker/test_queue_reconciliation.py +385 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/uv.lock +25 -25
- {gflow_cli-0.40.0 → gflow_cli-0.41.0/website}/docs/ARCHITECTURE.md +2 -2
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/website/docs/AUTHENTICATION.md +11 -8
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/website/docs/CONFIGURATION.md +8 -8
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/website/docs/KNOWN_ISSUES.md +36 -38
- {gflow_cli-0.40.0 → gflow_cli-0.41.0/website}/docs/USAGE.md +22 -24
- {gflow_cli-0.40.0 → gflow_cli-0.41.0/website}/docs/USER_GUIDE.md +85 -67
- gflow_cli-0.40.0/CONFIGURATION.md +0 -70
- gflow_cli-0.40.0/scripts/smoke_real_chrome_image.py +0 -416
- gflow_cli-0.40.0/src/gflow_cli/browser_manager.py +0 -777
- gflow_cli-0.40.0/src/gflow_cli/manifest.py +0 -60
- gflow_cli-0.40.0/src/gflow_cli/worker/queue.py +0 -179
- gflow_cli-0.40.0/tests/test_browser_manager.py +0 -1645
- gflow_cli-0.40.0/tests/test_documentation_gate.py +0 -34
- gflow_cli-0.40.0/tests/test_manifest.py +0 -56
- gflow_cli-0.40.0/tests/ui/test_app.py +0 -137
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/.claude/README.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/.claude/commands/gflow/active.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/.claude/commands/gflow/branch-review.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/.claude/commands/gflow/changelog.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/.claude/commands/gflow/check.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/.claude/commands/gflow/doc-review.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/.claude/commands/gflow/issue-assessment.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/.claude/commands/gflow/issue-resolve.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/.claude/commands/gflow/known-issues.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/.claude/commands/gflow/llm-council.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/.claude/commands/gflow/next.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/.claude/commands/gflow/plan.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/.claude/commands/gflow/pr-council-review.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/.claude/commands/gflow/predict.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/.claude/commands/gflow/release.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/.claude/commands/gflow/scenario.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/.claude/commands/gflow/sonar.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/.claude/commands/gflow/status.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/.gitattributes +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/.github/CODEOWNERS +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/.github/copilot-instructions.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/.github/dependabot.yml +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/.github/workflows/external-pr-triage.yml +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/.github/workflows/governance-advisory.yml +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/.github/workflows/governance-benchmark.yml +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/.github/workflows/release.yml +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/.gitleaks.toml +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/.pre-commit-config.yaml +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/.secrets.baseline +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/CLAUDE.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/CONTRIBUTING.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/DISCLAIMER.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/GEMINI.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/LICENSE +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/RELEASE.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/ROADMAP.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/conftest.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/deploy/PR-TRIAGE-AUTOPILOT-OPS.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docker-compose.yml +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/AGENT_GUIDE.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/AGENT_UI_E2E.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/AGENT_UI_RECON.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/ASSET_TAGGING_RECON.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/CHARACTER.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/CHARACTER_RECON.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/DATA_LAYER.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/DEBUGGING.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/DEMOS.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/DEVELOPMENT.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/EXTERNAL_STORAGE.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/GITHUB.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/GOVERNANCE_BENCHMARK.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/IMAGE_UPSCALE_RECON.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/INSTRUCTIONS.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/LIVE_VERIFICATION_data_layer.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/LIVE_VERIFICATION_image_batch.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/LIVE_VERIFICATION_v0.10.0.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/LIVE_VERIFICATION_v0.11.0.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/LIVE_VERIFICATION_v0.12.0.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/LIVE_VERIFICATION_v0.13.0.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/LIVE_VERIFICATION_v0.16.0.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/LIVE_VERIFICATION_v0.17.0.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/LIVE_VERIFICATION_v0.18.0.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/LIVE_VERIFICATION_v0.19.0.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/LIVE_VERIFICATION_v0.20.0.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/LIVE_VERIFICATION_v0.20.1.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/LIVE_VERIFICATION_v0.21.0.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/LIVE_VERIFICATION_v0.22.0.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/LIVE_VERIFICATION_v0.23.0.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/LIVE_VERIFICATION_v0.24.0.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/LIVE_VERIFICATION_v0.25.0.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/LIVE_VERIFICATION_v0.26.0.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/LIVE_VERIFICATION_v0.27.0.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/LIVE_VERIFICATION_v0.27.1.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/LIVE_VERIFICATION_v0.28.0.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/LIVE_VERIFICATION_v0.29.0.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/LIVE_VERIFICATION_v0.30.0.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/LIVE_VERIFICATION_v0.31.0.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/LIVE_VERIFICATION_v0.32.0.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/LIVE_VERIFICATION_v0.32.1.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/LIVE_VERIFICATION_v0.33.0.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/LIVE_VERIFICATION_v0.34.0.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/LIVE_VERIFICATION_v0.35.0.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/LIVE_VERIFICATION_v0.36.0.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/LIVE_VERIFICATION_v0.37.0.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/LIVE_VERIFICATION_v0.38.0.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/LIVE_VERIFICATION_v0.38.1.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/LIVE_VERIFICATION_v0.39.0.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/LIVE_VERIFICATION_v0.7.0.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/LIVE_VERIFICATION_v0.8.1.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/LIVE_VERIFICATION_v0.9.0.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/LIVE_VERIFICATION_v0.9.1.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/LIVE_VERIFICATION_video_download.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/MCP.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/MOVIE.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/PROMPT_EXPANSION.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/REFERENCE_STRATEGIES.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/SECURITY.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/TOOLS.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/assets/demo-split-pf.gif +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/assets/example-run.gif +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/assets/examples.webp +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/medium_tutorial.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/schemas/movie-handoff.schema.json +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/sonar-cleanup-tracker.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/superpowers/plans/2026-06-12-issue-174-library-ui-attach/PLAN.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/superpowers/plans/2026-06-22-mcp-server/PLAN.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/superpowers/plans/2026-06-22-mcp-server/PREDICT.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/superpowers/plans/2026-06-22-mcp-server/SCENARIO.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/superpowers/plans/2026-06-22-prompt-expansion/PLAN.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/superpowers/plans/2026-06-22-prompt-expansion/PREDICT.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/superpowers/plans/2026-06-22-prompt-expansion/SCENARIO.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/superpowers/plans/2026-06-24-gflow-studio-scaffold/PLAN.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/superpowers/plans/2026-06-24-rest-api-layer/PLAN.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/superpowers/plans/2026-06-26-mcp-e2e-test/PLAN.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/superpowers/plans/2026-07-08-pr-triage-autopilot/PLAN.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/superpowers/plans/2026-07-09-camoufox-adoption/PLAN.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/superpowers/plans/2026-07-14-storyboarding-and-visual-curation/PLAN.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/superpowers/plans/2026-07-18-asset-tagging/PLAN.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/superpowers/research/2026-06-27-tool-abstraction-evaluation.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/superpowers/specs/2026-06-29-issue-assessment-workflow-design.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/superpowers/specs/2026-07-04-pr-triage-autopilot-design.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/superpowers/specs/2026-07-18-asset-tagging-design.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/superpowers/spikes/2026-07-09-camoufox-waf-403.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/superpowers/spikes/2026-07-12-ui-cohort-backend-config.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/docs/superpowers/spikes/2026-07-17-production-readiness-assessment.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/eval/pr_triage_eval.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/eval/pr_triage_fixtures.json +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/examples/README.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/examples/batch_from_config.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/examples/multi_prompt_t2i.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/examples/sample_config.json +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/examples/sample_prompts.txt +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/examples/single_image_t2i.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/examples/workflow_chain.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/index.html +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/llms.txt +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/samples/README.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/samples/captured/01_upload_image.json +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/samples/captured/02_batchAsyncGenerateVideoText.json +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/samples/captured/03_batchCheckAsyncVideoGenerationStatus.json +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/samples/captured/04_archive_workflow.json +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/samples/captured/05_createProject.json +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/samples/captured/06_batchGenerateImages.json +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/samples/captured/07_batchGenerateImages_seeded.json +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/samples/captured/08_batchAsyncGenerateVideoStartAndEndImage.json +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/samples/captured/09_batchAsyncGenerateVideoReferenceImages.json +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/samples/captured/10_batchCheckAsyncVideoGenerationStatus_successful.json +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/samples/captured/11_batchCheckAsyncVideoGenerationStatus_failed.json +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/samples/captured/12_create_scene.json +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/samples/captured/13_sceneWorkflows_update.json +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/samples/captured/14_get_scene_workflows.json +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/samples/captured/15_commit_flowWorkflow.json +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/scripts/autopilot/Dockerfile.triage +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/scripts/autopilot/entrypoint.sh +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/scripts/autopilot/pr_triage_autopilot.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/scripts/autopilot/pr_triage_gate.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/scripts/autopilot/run_sandboxed_review.sh +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/scripts/ci/check_doc_links.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/scripts/ci/check_materiality.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/scripts/ci/check_release_artifacts.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/scripts/ci/check_repo_hygiene.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/scripts/debug_editor.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/scripts/debug_gen_settings.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/scripts/debug_settings.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/scripts/dev/_recording_client.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/scripts/dev/_spike_common.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/scripts/dev/active_plan.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/scripts/dev/analyze_agent_ui_capture.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/scripts/dev/capture_i2v_frame_slots_dom.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/scripts/dev/capture_i2v_intercept_submit.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/scripts/dev/capture_i2v_model_select_repro.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/scripts/dev/capture_i2v_post_bind_state.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/scripts/dev/capture_image_add_media_dom.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/scripts/dev/capture_locale_invariants.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/scripts/dev/cdp_drive_and_probe.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/scripts/dev/character_create_spike.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/scripts/dev/character_create_spike_v2.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/scripts/dev/dump_character_selectors.js +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/scripts/dev/make_project.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/scripts/dev/materiality_backtest.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/scripts/dev/monitor_pr_38.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/scripts/dev/patch_character.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/scripts/dev/skillopt/README.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/scripts/dev/skillopt/harness.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/scripts/dev/skillopt/tasks.json +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/scripts/dev/sonar-local-scan.sh +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/scripts/dev/sonar-pre-push-gate.sh +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/scripts/dev/spike_char_editor_dom.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/scripts/dev/spike_char_gen_capture.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/scripts/dev/spike_image_upscale_capture.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/scripts/dev/spike_image_upscale_drive.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/scripts/dev/spike_image_upscale_recaptcha_action.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/scripts/dev/spike_image_upscale_rest_probe.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/scripts/dev/spike_issue170_picker_locale_recon.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/scripts/dev/spike_issue174_library_ui_recon.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/scripts/dev/spike_issue313_agent_mode_controls.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/scripts/dev/spike_issue314_picker_filename_search.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/scripts/dev/spike_mode_roundtrip.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/scripts/dev/spike_mode_switch_agentic_to_classic.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/scripts/dev/spike_movie_attach_payload.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/scripts/dev/spike_movie_entity_recon.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/scripts/dev/spike_movie_gen_capture.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/scripts/dev/spike_movie_picker_select.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/scripts/dev/spike_movie_voice_list.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/scripts/dev/spike_patch_entity.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/scripts/dev/spike_patchright.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/scripts/diag/README.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/scripts/diag/capture_flow_traffic.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/scripts/diag/memory_profile.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/scripts/diag/recaptcha_mint.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/scripts/e2e/agentic_image_e2e.ps1 +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/scripts/e2e/capture_agent_toggle.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/scripts/record_demo.ps1 +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/scripts/smoke_image.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/scripts/smoke_video_editor.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/scripts/smoke_worker_style.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/scripts/spike_waf_camoufox.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/scripts/verify_chrome_auth_viability.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/skills/README.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/skills/changelog/SKILL.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/skills/doc-review/SKILL.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/skills/issue-assessment/SKILL.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/skills/issue-resolve/SKILL.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/skills/known-issues/SKILL.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/skills/llm-council/SKILL.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/skills/plan/SKILL.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/skills/pr-council-review/SKILL.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/skills/predict/SKILL.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/skills/release/SKILL.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/skills/scenario/SKILL.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/skills/sonar/SKILL.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/skills/status/SKILL.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/sonar-project.properties +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/__main__.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/_cli_helpers.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/api/__init__.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/api/_retry.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/api/_sapisidhash.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/api/character.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/api/image.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/api/image_upscale.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/api/recaptcha.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/api/routes.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/api/scene.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/api/transports/__init__.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/api/transports/_common.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/api/transports/_fingerprint.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/api/transports/drivers/__init__.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/api/transports/experimental/__init__.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/api/transports/mode_control.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/api/transports/ui_automation_video.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/api/video.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/auth/__init__.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/auth/base.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/auth/factory.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/auth/strategies.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/chain.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/cli.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/cli_character.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/cli_data.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/cli_image.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/cli_instructions.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/cli_models.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/cli_movie.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/cli_run.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/cli_scene.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/cli_tools.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/composition.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/config.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/data/__init__.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/data/migrations/0001_initial.sql +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/data/migrations/0002_add_cloud_storage.sql +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/data/migrations/0003_add_scene_tables.sql +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/data/migrations/0004_add_scene_output_path.sql +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/data/migrations/0005_add_chain_links.sql +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/data/migrations/0006_add_operations_metadata.sql +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/data/migrations/0007_queue.sql +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/data/migrations/0008_add_operation_expanded_prompt.sql +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/data/migrations/__init__.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/data/models.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/data/queries.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/data/redaction.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/data/repository.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/data/store.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/exceptions.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/image_batch.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/json_output.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/mcp/__init__.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/mcp/prompts.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/mcp/resources.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/mcp/server.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/media.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/movie_manifest.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/observability.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/profile_store.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/services/__init__.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/services/character_create.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/storage.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/tools/__init__.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/tools/banned.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/tools/builtin/__init__.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/tools/builtin/creative-director.toml +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/tools/builtin/reverse-engineer.toml +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/tools/builtin/storyboard.toml +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/tools/expander.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/tools/invocation.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/tools/loader.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/tools/registry.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/tools/runtime.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/tools/spec.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/src/gflow_cli/ui/server.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tasks/lessons.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/test_assets/sample_batch.json +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/test_assets/sample_batch.tsv +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/test_assets/sample_batch_invalid.tsv +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/__init__.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/api/__init__.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/api/fixtures/character_gen_response.json +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/api/fixtures/patch_entity_response.json +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/api/test_aisandbox_auth_error.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/api/test_aisandbox_auth_headers.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/api/test_bearer_redaction.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/api/test_character.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/api/test_client_character.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/api/test_client_delete_characters.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/api/test_client_generate_character.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/api/test_client_image.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/api/test_client_launch_kwargs.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/api/test_client_patch_entity.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/api/test_client_scene.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/api/test_client_upscale.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/api/test_concurrency.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/api/test_dto.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/api/test_engine.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/api/test_image.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/api/test_image_dto.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/api/test_image_upscale.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/api/test_post_json_aisandbox_auth.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/api/test_recaptcha.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/api/test_retry.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/api/test_routes.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/api/test_routes_character.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/api/test_routes_scene.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/api/test_sapisidhash_helper.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/api/test_scene_models.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/api/test_video.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/api/test_video_request.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/api/transports/__init__.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/api/transports/conftest.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/api/transports/drivers/__init__.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/api/transports/drivers/test_factory.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/api/transports/drivers/test_ui_mode.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/api/transports/test_base.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/api/transports/test_common.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/api/transports/test_factory.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/api/transports/test_fingerprint.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/api/transports/test_mode_control.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/api/transports/test_selector_symmetry.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/api/transports/test_transport_timeout.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/api/transports/test_ui_automation_image_mode.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/api/transports/test_ui_automation_video.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/api/transports/test_ui_character_editor.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/auth/strategies/test_factory.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/autopilot/test_pr_triage_autopilot.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/cli/__init__.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/cli/test_cli_auth_list.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/cli/test_cli_character.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/cli/test_cli_character_create.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/cli/test_cli_data.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/cli/test_cli_data_errors.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/cli/test_cli_image.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/cli/test_cli_image_seed_removed.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/cli/test_cli_image_selector_drift.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/cli/test_cli_image_upscale.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/cli/test_cli_instructions.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/cli/test_cli_models.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/cli/test_cli_movie.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/cli/test_cli_run.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/cli/test_cli_scene.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/cli/test_cli_tools.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/cli/test_cli_video_chain.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/cli/test_failure_funnel.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/cli/test_helpers.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/cli/test_movie_manifest.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/cli/test_movie_manifest_style_variants.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/cli/test_settings_validation.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/cli/test_t2i_multi_prompt.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/composition/test_character.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/composition/test_compose_prompt.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/composition/test_handoff.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/composition/test_style_variants.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/composition/test_style_variants_e2e.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/conftest.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/data/__init__.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/data/test_failure_recording.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/data/test_find_incomplete_character.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/data/test_models.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/data/test_packaging.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/data/test_recorder_character.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/data/test_redaction.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/data/test_repository.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/data/test_scene_persistence.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/data/test_settings_and_errors.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/dev/test_recording_client.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/e2e/__init__.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/e2e/conftest.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/e2e/test_agentic_count_enforcement_e2e.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/e2e/test_aisandbox_auth_live.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/e2e/test_asset_tagging_e2e.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/e2e/test_auth_verification_e2e.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/e2e/test_chain_e2e.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/e2e/test_character_create_e2e.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/e2e/test_data_layer_e2e.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/e2e/test_entity_smuggling_e2e.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/e2e/test_i2v_flags_e2e.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/e2e/test_image_batch_e2e.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/e2e/test_image_i2i_ref_cap_e2e.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/e2e/test_json_output_e2e.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/e2e/test_live_agentic_instructions.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/e2e/test_locale_selectors_e2e.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/e2e/test_scene_compose_live.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/e2e/test_tools_e2e.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/e2e/test_transports_e2e.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/e2e/test_video_r2v_ref_cap_e2e.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/e2e/test_video_t2v_e2e.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/features/__init__.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/features/asset_tagging.feature +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/features/auth.feature +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/features/auth_login.feature +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/features/character_create.feature +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/features/character_read.feature +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/features/conftest.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/features/image.feature +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/features/image_upscale.feature +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/features/instructions.feature +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/features/locale_picker_include.feature +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/features/test_asset_tagging_steps.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/features/test_auth_login_steps.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/features/test_auth_steps.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/features/test_character_create_steps.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/features/test_character_read_steps.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/features/test_image_steps.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/features/test_image_upscale_steps.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/features/test_instructions_steps.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/features/test_locale_picker_include_steps.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/features/test_step_collision_guard.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/features/test_video_chain_steps.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/features/video_agent_ui.feature +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/features/video_chain.feature +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/fixtures/__init__.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/fixtures/seeded_catalog.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/image_batch/__init__.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/image_batch/test_image_manifest.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/image_batch/test_jitter_config.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/image_batch/test_observability_events.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/integration/__init__.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/integration/conftest.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/integration/constants.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/integration/test_storage_gcs.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/integration/test_storage_s3.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/mcp/__init__.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/mcp/conftest.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/mcp/test_server.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/mcp/test_stdio_transport.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/mcp/test_tools_helpers.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/mcp/test_tools_instructions.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/mcp/test_tools_wired.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/scripts/test_analyze_agent_ui_capture.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/scripts/test_capture_locale_invariants.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/scripts/test_check_materiality.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/scripts/test_check_release_artifacts.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/scripts/test_check_repo_hygiene.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/scripts/test_materiality_backtest.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/services/__init__.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/services/test_character_create_redaction.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/services/test_character_create_saga.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/services/test_character_gen_no_direct_post.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/services/test_mentions_observability.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/services/test_mentions_parse.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/smoke/__init__.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/smoke/test_profile_account_smoke.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/smoke/test_real_flow.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/test_auth.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/test_chain.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/test_chain_manifest.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/test_cli_data.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/test_config.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/test_conftest_isolation.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/test_data_queries.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/test_errors_403.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/test_json_output.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/test_marker_registry.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/test_media.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/test_observability.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/test_paths.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/test_profile_store.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/test_smoke.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/tools/__init__.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/tools/test_banned.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/tools/test_expander.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/tools/test_invocation.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/tools/test_loader.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/tools/test_registry.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/tools/test_runtime.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/tests/tools/test_spec.py +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/website/docs/CHARACTER.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/website/docs/DATA_LAYER.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/website/docs/DEBUGGING.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/website/docs/DEVELOPMENT.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0/website}/docs/E2E_TESTING.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/website/docs/EXTERNAL_STORAGE.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/website/docs/INSTRUCTIONS.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/website/docs/MCP.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/website/docs/MOVIE.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/website/docs/PROMPT_EXPANSION.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/website/docs/SECURITY.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/website/docs/TOOLS.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/website/docs/agents.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/website/docs/index.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/website/docs/installation.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/website/docs/quickstart.md +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/website/docs/stylesheets/extra.css +0 -0
- {gflow_cli-0.40.0 → gflow_cli-0.41.0}/website/mkdocs.yml +0 -0
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Two-part gate for gflow-cli feature work — pre-flight state check at the start, live-verification against real Flow before claiming done.
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# `/gflow:live-verify` — Live-verification enforcement
|
|
6
|
+
|
|
7
|
+
**Read `skills/live-verify/SKILL.md` and follow the protocol**, passing `$ARGUMENTS` if given.
|
|
8
|
+
|
|
9
|
+
> Do **not** call `Skill(skill="live-verify")` — read the file directly.
|
|
@@ -102,17 +102,21 @@
|
|
|
102
102
|
# auto = text on TTY, json when piped (default)
|
|
103
103
|
# GFLOW_CLI_LOG_FORMAT=auto
|
|
104
104
|
|
|
105
|
-
# Per-worker Playwright Page-pool size
|
|
106
|
-
#
|
|
107
|
-
#
|
|
108
|
-
#
|
|
105
|
+
# Per-worker Playwright Page-pool size (1-16). FlowApiClient opens N Pages
|
|
106
|
+
# inside one shared persistent BrowserContext. No current CLI command fans
|
|
107
|
+
# out multiple generations concurrently through this pool, so raising it has
|
|
108
|
+
# no effect today. ~30-60 MiB memory per Page on Chromium headless if that
|
|
109
|
+
# changes; don't exceed 8 without measuring. Shipped in v0.4.0a2.
|
|
109
110
|
# GFLOW_CLI_CONCURRENCY=1
|
|
110
111
|
|
|
111
112
|
# Run Playwright in headless mode for non-`auth login` commands (true|false).
|
|
112
|
-
# Default:
|
|
113
|
-
#
|
|
114
|
-
#
|
|
115
|
-
#
|
|
113
|
+
# Default: false — headed real Chrome is the PRODUCTION default, not a
|
|
114
|
+
# fallback. The ui_automation transport (the only production transport)
|
|
115
|
+
# requires headed Chrome: reCAPTCHA Enterprise rejects headless Chromium
|
|
116
|
+
# outright (immediate 403). Only set true for CI/CD on a non-ui_automation
|
|
117
|
+
# transport (bearer/sapisidhash, experimental). For WAF-sensitive runs, pin
|
|
118
|
+
# GFLOW_CLI_HEADLESS=false explicitly rather than relying on the default.
|
|
119
|
+
# GFLOW_CLI_HEADLESS=false
|
|
116
120
|
|
|
117
121
|
# Browser automation engine — playwright (default) | patchright
|
|
118
122
|
# patchright is an OPT-IN, drop-in patched Playwright (Chromium) that avoids the
|
|
@@ -87,6 +87,37 @@ jobs:
|
|
|
87
87
|
path: coverage.xml
|
|
88
88
|
retention-days: 1
|
|
89
89
|
|
|
90
|
+
# ── Focused OS matrix: ProfileLease cross-process contract (Task D2) ──────
|
|
91
|
+
# Everything else in this file runs Ubuntu-only (the `test` job above).
|
|
92
|
+
# This job exists because ProfileLease's kernel lock is genuinely
|
|
93
|
+
# OS-specific (msvcrt.locking on Windows vs. fcntl.flock on POSIX) and D1's
|
|
94
|
+
# local Windows-only run left the POSIX fcntl branch reasoned-but-unexecuted
|
|
95
|
+
# (see .superpowers/sdd/task-D1-report.md). Runs ONLY the lease unit +
|
|
96
|
+
# subprocess tests, not the full suite.
|
|
97
|
+
profile-lease-matrix:
|
|
98
|
+
name: ProfileLease (${{ matrix.os }})
|
|
99
|
+
runs-on: ${{ matrix.os }}
|
|
100
|
+
env:
|
|
101
|
+
PYTHONUTF8: "1"
|
|
102
|
+
strategy:
|
|
103
|
+
fail-fast: false
|
|
104
|
+
matrix:
|
|
105
|
+
os: [windows-latest, macos-latest, ubuntu-latest]
|
|
106
|
+
steps:
|
|
107
|
+
- uses: actions/checkout@v7
|
|
108
|
+
|
|
109
|
+
- name: Install uv
|
|
110
|
+
uses: astral-sh/setup-uv@v7
|
|
111
|
+
|
|
112
|
+
- name: Set up Python
|
|
113
|
+
run: uv python install 3.13
|
|
114
|
+
|
|
115
|
+
- name: Install deps
|
|
116
|
+
run: uv sync --extra dev
|
|
117
|
+
|
|
118
|
+
- name: ProfileLease unit + subprocess tests
|
|
119
|
+
run: uv run python -m pytest tests/test_profile_lease.py tests/test_profile_lease_subprocess.py -q
|
|
120
|
+
|
|
90
121
|
# ── SonarCloud analysis ───────────────────────────────────────────────────
|
|
91
122
|
sonar:
|
|
92
123
|
name: SonarCloud analysis
|
|
@@ -26,8 +26,8 @@ jobs:
|
|
|
26
26
|
build:
|
|
27
27
|
runs-on: ubuntu-latest
|
|
28
28
|
steps:
|
|
29
|
-
- uses: actions/checkout@
|
|
30
|
-
- uses: actions/setup-python@
|
|
29
|
+
- uses: actions/checkout@v7
|
|
30
|
+
- uses: actions/setup-python@v7
|
|
31
31
|
with:
|
|
32
32
|
python-version: "3.12"
|
|
33
33
|
- name: Install MkDocs Material
|
|
@@ -40,7 +40,7 @@ jobs:
|
|
|
40
40
|
mkdir -p _site
|
|
41
41
|
cp index.html _site/
|
|
42
42
|
cp -r website/site _site/docs
|
|
43
|
-
- uses: actions/upload-pages-artifact@
|
|
43
|
+
- uses: actions/upload-pages-artifact@v5
|
|
44
44
|
with:
|
|
45
45
|
path: _site
|
|
46
46
|
|
|
@@ -52,4 +52,4 @@ jobs:
|
|
|
52
52
|
url: ${{ steps.deployment.outputs.page_url }}
|
|
53
53
|
steps:
|
|
54
54
|
- id: deployment
|
|
55
|
-
uses: actions/deploy-pages@
|
|
55
|
+
uses: actions/deploy-pages@v5
|
|
@@ -58,10 +58,6 @@ gflow-output/
|
|
|
58
58
|
!test_assets/fixtures/**/*.jpeg
|
|
59
59
|
samples/*.captured.json # sandbox-recorded API exchanges may contain PII
|
|
60
60
|
|
|
61
|
-
# CDP browser session lock files (contain PID, port, profile name)
|
|
62
|
-
.gflow-cdp.lock
|
|
63
|
-
**/.gflow-cdp.lock
|
|
64
|
-
|
|
65
61
|
# Runtime artefact dirs written by smoke/debug scripts — belong under tmp/ only
|
|
66
62
|
test_assets/smoke_*/
|
|
67
63
|
test_assets/debug_*/
|
|
@@ -8,8 +8,8 @@ Supported tools that auto-discover this file: Cursor, Codex, Aider, Jules, Devin
|
|
|
8
8
|
|
|
9
9
|
- Unofficial Python CLI for [Google Flow](https://labs.google/fx/tools/flow) — drives Veo (image-to-video, text-to-video) and Imagen (text-to-image) generations from the terminal by reverse-engineering Flow's private REST API at `aisandbox-pa.googleapis.com`.
|
|
10
10
|
- Python 3.11+ · `uv`-managed · `hatchling` builds · Playwright Chromium transport · `pyright` strict · `ruff` · `pytest`.
|
|
11
|
-
- Single-package modular monolith. Top-level modules under `src/gflow_cli/`: `api/`, `auth/`, `data/`, `mcp/`, `services/`, `tools/`, `ui/`, `worker/`, `browser_manager.py`, `cli.py`, `_cli_helpers.py`, `cli_character.py`, `cli_data.py`, `cli_image.py`, `cli_instructions.py`, `cli_models.py`, `cli_movie.py`, `cli_run.py`, `cli_scene.py`, `cli_tools.py`, `cli_video.py`, `chain.py`, `chain_manifest.py`, `composition.py`, `config.py`, `errors.py`, `exceptions.py`, `image_batch.py`, `
|
|
12
|
-
- Command surface: `gflow auth`, `gflow image` (t2i/i2i/batch/upload/upscale), `gflow video` (t2v/i2v/r2v/chain — `batch`
|
|
11
|
+
- Single-package modular monolith. Top-level modules under `src/gflow_cli/`: `api/`, `auth/`, `data/`, `mcp/`, `services/`, `tools/`, `ui/`, `worker/`, `browser_manager.py`, `cli.py`, `_cli_helpers.py`, `cli_character.py`, `cli_data.py`, `cli_image.py`, `cli_instructions.py`, `cli_models.py`, `cli_movie.py`, `cli_run.py`, `cli_scene.py`, `cli_tools.py`, `cli_video.py`, `chain.py`, `chain_manifest.py`, `composition.py`, `config.py`, `errors.py`, `exceptions.py`, `image_batch.py`, `movie_manifest.py`, `observability.py`, `paths.py`, `profile_store.py`.
|
|
12
|
+
- Command surface: `gflow auth`, `gflow image` (t2i/i2i/batch/upload/upscale), `gflow video` (t2v/i2v/r2v/chain — no `batch` subcommand; the nonfunctional stub was removed, loop `gflow video t2v`/`i2v` from the shell for multi-clip runs), `gflow character` (create/list/show/rm/voices — reusable project-scoped Flow Character entities), `gflow scene` (create/show — Add Clip / Scenes, with `create --output` for credit-free server-side extended video), `gflow instructions` (persistent Agent-Mode brief cards — add/list/enable/disable/rm/apply/toggle-mode, credits-free, `--project` required), `gflow movie` (run/template — multi-scene manifest pipeline), `gflow tools` (list/show/run — prompt-rewriting tools, also `--tool` on generation commands), `gflow data` (catalog queries), `gflow models`, `gflow run`, `gflow mcp` (run/setup — stdio MCP server), and `gflow serve` (HTTP/SSE).
|
|
13
13
|
- Requires a Google AI Ultra or Pro subscription with Flow access. All generations bill against the user's own Google account.
|
|
14
14
|
|
|
15
15
|
## Headed-browser dependency (architectural reality)
|
|
@@ -57,7 +57,7 @@ Or invoke the wrapper: `/gflow:check`.
|
|
|
57
57
|
|
|
58
58
|
- Type hints everywhere; `pyright` strict on `src/gflow_cli`.
|
|
59
59
|
- Structured logging only (`structlog`) — **never** raw `print()` or `import logging` in `src/`.
|
|
60
|
-
- Errors as RFC 9457 Problem Details with stable per-class exit codes (3–
|
|
60
|
+
- Errors as RFC 9457 Problem Details with stable per-class exit codes (3–30, e.g. 11 is `ConfigurationError` — including `ProfileLockedError` for same-profile lease contention, 16 is the `DataStoreError` family, 19 `SceneConcatError`, 20 `FrameExtractionError`, 21 `ChainPartialError`, 22 `UpscaleUnavailableError`, 25 `FlowAgentUiError`, 28 `UiModeUnavailableError`, 29 `MentionIndexUnavailableError`, 30 `QueueSchemaError`). 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
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.
|
|
63
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`.
|
|
@@ -78,6 +78,7 @@ These rules exist because docs alone don't bind under momentum: a "check open PR
|
|
|
78
78
|
- **Truth is the CLI and running the code — not IDE/LSP "reminder" diagnostics.** Editor / `pyright`-in-worktree warnings go stale for an entire session and throw false positives (especially across multiple worktrees). Confirm with `ruff` / `pyright` / `pytest` from the terminal — or trust the worktree's own venv — never an IDE squiggle.
|
|
79
79
|
- **Verify third-party runtime behavior empirically before wiring it in.** Don't assume how an external library, API, or browser actually behaves — exercise it once and observe, then build on the observed contract.
|
|
80
80
|
- **If a claim can't be verified in the current environment, it's LIKELY — not CONFIRMED.** Keep the issue open, reference it with `Refs #N` (not `Closes #N`), and ship diagnostics rather than a blind fix. When you can't reproduce it, hand the fix to whoever can.
|
|
81
|
+
- **This project reverse-engineers a blackbox.** gflow-cli doesn't own Google Flow — it drives real Flow through inspected HAR/DOM/browser-log behavior. Offline checks (types, lint, unit/BDD tests) verify *our* code does what we think it does; they cannot verify Flow still behaves the way we captured it. Every feature that touches a generation path is **live-verified**, not just offline-tested, before it's called done — see `/gflow:live-verify`.
|
|
81
82
|
|
|
82
83
|
## Skills reference (cross-tool)
|
|
83
84
|
|
|
@@ -98,6 +99,7 @@ The `skills/` directory ships installable agent skill docs in plain Markdown wit
|
|
|
98
99
|
| `changelog` | [`skills/changelog/SKILL.md`](skills/changelog/SKILL.md) | Unreleased changes + last tagged version |
|
|
99
100
|
| `known-issues` | [`skills/known-issues/SKILL.md`](skills/known-issues/SKILL.md) | Open/mitigated known issues — before auth/reCAPTCHA work |
|
|
100
101
|
| `sonar` | [`skills/sonar/SKILL.md`](skills/sonar/SKILL.md) | Drive the SonarCloud quality gate to zero for a PR/branch |
|
|
102
|
+
| `live-verify` | [`skills/live-verify/SKILL.md`](skills/live-verify/SKILL.md) | Pre-flight state check at start of work; live-verification against real Flow before claiming done |
|
|
101
103
|
| `doc-review` | [`skills/doc-review/SKILL.md`](skills/doc-review/SKILL.md) | Council-driven documentation audit before a release |
|
|
102
104
|
| `release` | [`skills/release/SKILL.md`](skills/release/SKILL.md) | Cut a release — bump, CHANGELOG, tag, push, back-merge |
|
|
103
105
|
|
|
@@ -7,6 +7,65 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.41.0] — 2026-07-20
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- **Cross-process profile lease** ([#357]): new `ProfileLease` with
|
|
15
|
+
process-local guard + kernel advisory lock (`msvcrt` on Windows, `fcntl`
|
|
16
|
+
on POSIX), keyed by canonical profile dir. `ProfileLockedError` (exit 11)
|
|
17
|
+
on contention. Integrated at all 10 persistent-context-owning boundaries.
|
|
18
|
+
Daemon's overwriteable `profile.lock` removed.
|
|
19
|
+
- **Versioned worker queue payloads** ([#357]): `schema_version: 1` codec
|
|
20
|
+
validates before Playwright starts; unknown versions raise typed
|
|
21
|
+
`QueueSchemaError` (exit 30). Legacy V0 (missing field) still accepted.
|
|
22
|
+
- **Atomic queue task claims** ([#357]): single SQLite `BEGIN IMMEDIATE`
|
|
23
|
+
transaction (select → decode → fail-invalid-without-browser → conditional
|
|
24
|
+
`pending→processing`) shared by daemon and MCP; duplicate per-profile lock
|
|
25
|
+
maps removed. Checkpointed execution phases (`claimed → submit_attempted →
|
|
26
|
+
remote_started → terminal`) with conservative `may_have_spent`.
|
|
27
|
+
- **`/gflow:live-verify` skill**: pre-flight state check + per-feature
|
|
28
|
+
live-verification gate before claiming feature completion.
|
|
29
|
+
- **Driver honesty improvements** ([#357]): removed classic driver's
|
|
30
|
+
`await_images()` that only raised; replaced late `driver._transport = self`
|
|
31
|
+
mutation with typed `SupportsSendPrompt` injection; agentic submit takes
|
|
32
|
+
request + expected count directly. Frozen `TransportSetup` applied through
|
|
33
|
+
public `apply_setup()` seam replacing client writes to transport-private
|
|
34
|
+
fields.
|
|
35
|
+
|
|
36
|
+
### Changed
|
|
37
|
+
|
|
38
|
+
- **Cancellation-safe browser teardown** ([#357]): per-step
|
|
39
|
+
`shield(wait_for(...))` bounded cleanup in required order (stop work →
|
|
40
|
+
cancel worker → persist state → close browser/driver → close stores →
|
|
41
|
+
release lease), re-raising original cancellation last.
|
|
42
|
+
- **Mention-index outages fail closed** ([#357]): `MentionIndexUnavailableError`
|
|
43
|
+
(exit 29) with unavailable source name; mention-free prompts stay
|
|
44
|
+
pass-through. Empty source ≠ unavailable source.
|
|
45
|
+
- **`OperationRecorder`/chain-repo datastore ownership** ([#357]): stores
|
|
46
|
+
only close the `DataStore` they create; injected stores never closed by a
|
|
47
|
+
non-owner.
|
|
48
|
+
- External-CDP browser lifecycle removed by evidence (no production
|
|
49
|
+
consumer, unauthenticated debug port, ambiguous ownership, recorded
|
|
50
|
+
WAF-rejection); Chrome discovery/channel helpers preserved.
|
|
51
|
+
|
|
52
|
+
### Removed
|
|
53
|
+
|
|
54
|
+
- **`gflow video batch`** — the manifest-driven video batch command was
|
|
55
|
+
removed. It never worked end-to-end; every invocation exited immediately
|
|
56
|
+
with a stub error before reaching Flow. `gflow image batch` (manifest-driven
|
|
57
|
+
image generation) is unaffected and remains supported.
|
|
58
|
+
- External-CDP browser lifecycle (no production consumer).
|
|
59
|
+
|
|
60
|
+
### Security
|
|
61
|
+
|
|
62
|
+
- Cancellation-safe teardown prevents resource leaks on interrupt.
|
|
63
|
+
- Profile lease kernel advisory lock prevents concurrent profile access
|
|
64
|
+
across processes.
|
|
65
|
+
|
|
66
|
+
[#357]: https://github.com/ffroliva/gflow-cli/pull/357
|
|
67
|
+
[`docs/LIVE_VERIFICATION_v0.40.0-production-readiness.md`]: https://github.com/ffroliva/gflow-cli/blob/main/docs/LIVE_VERIFICATION_v0.40.0-production-readiness.md
|
|
68
|
+
|
|
10
69
|
## [0.40.0] — 2026-07-19
|
|
11
70
|
|
|
12
71
|
### Added
|
|
@@ -2110,7 +2169,8 @@ shell-script template that branches on these codes.
|
|
|
2110
2169
|
|
|
2111
2170
|
First skeleton. Not functional end-to-end yet.
|
|
2112
2171
|
|
|
2113
|
-
[Unreleased]: https://github.com/ffroliva/gflow-cli/compare/v0.
|
|
2172
|
+
[Unreleased]: https://github.com/ffroliva/gflow-cli/compare/v0.41.0...HEAD
|
|
2173
|
+
[0.41.0]: https://github.com/ffroliva/gflow-cli/compare/v0.40.0...v0.41.0
|
|
2114
2174
|
[0.40.0]: https://github.com/ffroliva/gflow-cli/compare/v0.39.0...v0.40.0
|
|
2115
2175
|
[0.39.0]: https://github.com/ffroliva/gflow-cli/compare/v0.38.1...v0.39.0
|
|
2116
2176
|
[0.38.1]: https://github.com/ffroliva/gflow-cli/compare/v0.38.0...v0.38.1
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# gflow-cli Configuration Reference
|
|
2
|
+
|
|
3
|
+
## Environment variables
|
|
4
|
+
|
|
5
|
+
| Env var | Default | Description |
|
|
6
|
+
|---|---|---|
|
|
7
|
+
| `GFLOW_CLI_HOME` | Platform data dir | Root directory for profiles and config. |
|
|
8
|
+
| `GFLOW_CLI_OUTPUT_DIR` | `~/Downloads/gflow-cli` | Where generated images and videos are saved. |
|
|
9
|
+
| `CHROME_BINARY` | (autodetect) | Override Chrome binary path. Falls back to platform-standard locations. |
|
|
10
|
+
| `GFLOW_CLI_CONCURRENCY` | `4` | Maximum parallel API requests per batch. |
|
|
11
|
+
| `GFLOW_CLI_GEMINI_API_KEY` | _(unset)_ | Public Gemini key enabling prompt expansion (`-e`/`--expand`). Unset = expansion is a graceful no-op. [Get one](https://aistudio.google.com/apikey). |
|
|
12
|
+
| `GFLOW_CLI_GEMINI_MODEL` | `gemini-2.5-flash` | Gemini model used for prompt expansion. |
|
|
13
|
+
| `GFLOW_LIVE` | _(unset)_ | Set to `1` to enable live-API test markers (`@pytest.mark.live`). |
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Browser
|
|
18
|
+
|
|
19
|
+
There is no `GFLOW_CLI_BROWSER` mode switch — the production path is
|
|
20
|
+
`UiAutomationTransport`, a Playwright persistent context using Playwright's
|
|
21
|
+
own internal CDP port (never externally exposed). A separate packaged
|
|
22
|
+
CDP attach/spawn lifecycle (`auto`/`fresh`/`cdp:<port>` modes, a port-probe
|
|
23
|
+
range, and a `.gflow-cdp.lock` file) previously existed in
|
|
24
|
+
`browser_manager.py` but had no CLI wiring and no production consumer; it
|
|
25
|
+
was removed 2026-07-19 (see `.superpowers/sdd/cdp-decision.md`). Only Chrome
|
|
26
|
+
binary discovery remains, used to pick a channel for the real transport.
|
|
27
|
+
|
|
28
|
+
### Chrome binary autodetection order
|
|
29
|
+
|
|
30
|
+
1. `CHROME_BINARY` env var (checked first — always wins)
|
|
31
|
+
2. `shutil.which("chrome")` / `shutil.which("google-chrome")` / `shutil.which("chromium")`
|
|
32
|
+
3. Platform-standard paths:
|
|
33
|
+
- **Windows**: `C:\Program Files\Google\Chrome\Application\chrome.exe`,
|
|
34
|
+
`C:\Program Files (x86)\Google\Chrome\Application\chrome.exe`,
|
|
35
|
+
`%LOCALAPPDATA%\Google\Chrome\Application\chrome.exe`
|
|
36
|
+
- **macOS**: `/Applications/Google Chrome.app/Contents/MacOS/Google Chrome`
|
|
37
|
+
- **Linux**: `/usr/bin/google-chrome`, `/usr/bin/chromium`, `/usr/bin/chromium-browser`
|
|
38
|
+
|
|
39
|
+
If Chrome is not found, gflow-cli raises a `ConfigurationError` with an install hint.
|
|
@@ -275,26 +275,6 @@ Re-running `auth login` reuses the existing profile dir (you typically just clic
|
|
|
275
275
|
|
|
276
276
|
---
|
|
277
277
|
|
|
278
|
-
### Same profile can't be used in parallel
|
|
279
|
-
|
|
280
|
-
- **Status:** Open (by design) · **Severity:** Low · **Affects:** all versions
|
|
281
|
-
|
|
282
|
-
Chromium refuses to open two persistent contexts on the same `user-data-dir` simultaneously. So running two concurrent `gflow ...` calls with the same `--profile` will fail the second one with a "ProcessSingleton: profile is locked" error.
|
|
283
|
-
|
|
284
|
-
**Workaround:** use different profiles for parallel work.
|
|
285
|
-
|
|
286
|
-
```bash
|
|
287
|
-
# Terminal 1
|
|
288
|
-
gflow video batch ./batch-a.tsv --profile work
|
|
289
|
-
|
|
290
|
-
# Terminal 2 — different profile, same time, OK
|
|
291
|
-
gflow video batch ./batch-b.tsv --profile personal
|
|
292
|
-
```
|
|
293
|
-
|
|
294
|
-
**Roadmap:** Phase 4 (v0.4.0a2) added concurrency *inside* one `gflow-cli` process via `GFLOW_CLI_CONCURRENCY=N` (per-worker Page pool on one shared BrowserContext). Cross-process same-profile serialization is a Chromium constraint we cannot work around without rewriting the auth model — multiple shells against the same profile remains a "use different profiles" workaround.
|
|
295
|
-
|
|
296
|
-
---
|
|
297
|
-
|
|
298
278
|
### Chromium cookie database locks block yt-dlp integrations (Instagram/restricted download paths)
|
|
299
279
|
|
|
300
280
|
- **Status:** Mitigated · **Severity:** Low-Medium · **Affects:** any downstream helper calling `yt-dlp` (including `claude-video`, `cg-decode`/`refanalyzer`, or `experience-vault`)
|
|
@@ -364,36 +344,35 @@ playwright._impl._errors.TimeoutError: Locator.click: Timeout 30000ms exceeded.
|
|
|
364
344
|
|
|
365
345
|
---
|
|
366
346
|
|
|
367
|
-
###
|
|
347
|
+
### `gflow serve` / MCP worker queue: interrupted post-submit tasks need manual reconciliation
|
|
368
348
|
|
|
369
|
-
- **Status:** Open · **Severity:** Low
|
|
349
|
+
- **Status:** Open (by design — no automated reconciliation) · **Severity:** Low · **Affects:** `gflow serve` daemon and MCP worker paths only (not the plain CLI, which has no queue)
|
|
370
350
|
|
|
371
|
-
|
|
372
|
-
- Veo I2V: `9:16`, `16:9`, `1:1`
|
|
373
|
-
- Imagen: `1:1`, `9:16`, `16:9`, `4:3`, `3:4`
|
|
351
|
+
The worker queue (`generation_queue`, used by the `gflow serve` daemon and MCP tool calls) checkpoints every task's progress through `claimed` → `submit_attempted` → `remote_started` → terminal. If a task is interrupted (daemon restart, crash, or cancellation) while still `claimed` (before any submit), gflow-cli safely marks it `failed` — nothing was spent, safe to retry. But if it's interrupted at `submit_attempted` or `remote_started` — **after** the credit-spending submit click may have fired — it is marked `indeterminate` instead: a credit *may* have been spent and the outcome is unknown. An `indeterminate` task is **never** silently reported as `failed` and **never** auto-resubmitted (that could double-spend a credit for one generation).
|
|
374
352
|
|
|
375
|
-
|
|
353
|
+
**Why this can't be resolved automatically today:** Flow's generation-status REST endpoint rejects a bare, cookie-only `page.request` re-check with HTTP 401 — only a live, authenticated Playwright SPA re-poll (opening the project page and reading the DOM) can turn a preserved handle back into a real status, and that live re-poll path is not wired into recovery yet (tracked for a future phase; see the C1 handle-spike notes in `docs/superpowers/specs/2026-07-19-production-readiness-hardening-design.md` Appendix A).
|
|
376
354
|
|
|
377
|
-
|
|
355
|
+
**Manual reconciliation:** an `indeterminate` row's checkpoint retains whatever handle/project info was captured before interruption. To resolve one by hand: open the relevant Flow project in the browser and check whether the expected asset appears.
|
|
356
|
+
- **Found** — the generation completed; no action needed (the credit was spent as intended, just not auto-recorded locally).
|
|
357
|
+
- **Not found after a few minutes** — it likely never completed; safe to resubmit the same prompt manually.
|
|
378
358
|
|
|
379
|
-
|
|
359
|
+
**Queue payload schema (V0/V1):** the queue's `payload_json` carries an additive `schema_version` key. A payload with no `schema_version` key is legacy **V0** and decodes with the same field lookups as **V1** (the shape is otherwise identical) — both remain readable. The codec always *writes* the current version (`1`) on any re-encode. Any other version is treated as unknown and rejected with `QueueSchemaError` (**exit code 30**) rather than interpreted optimistically — this is a fail-closed guard against decoding a payload written by an incompatible future (or hand-edited) version.
|
|
380
360
|
|
|
381
|
-
|
|
361
|
+
---
|
|
382
362
|
|
|
383
|
-
|
|
363
|
+
### Aspect-ratio support depends on the Veo / Imagen model version
|
|
384
364
|
|
|
385
|
-
**
|
|
365
|
+
- **Status:** Open · **Severity:** Low
|
|
386
366
|
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
gflow video batch manifest.remaining.tsv
|
|
391
|
-
```
|
|
367
|
+
Currently confirmed:
|
|
368
|
+
- Veo I2V: `9:16`, `16:9`, `1:1`
|
|
369
|
+
- Imagen: `1:1`, `9:16`, `16:9`, `4:3`, `3:4`
|
|
392
370
|
|
|
393
|
-
|
|
371
|
+
Other ratios may be silently rejected or coerced server-side. We validate in the CLI to whitelisted values to fail fast.
|
|
394
372
|
|
|
395
373
|
---
|
|
396
374
|
|
|
375
|
+
|
|
397
376
|
### REST API 401 — all `aisandbox-pa.googleapis.com` generation endpoints blocked
|
|
398
377
|
|
|
399
378
|
- **Status:** **RESOLVED in v0.7.0** — image generation live-verified end-to-end
|
|
@@ -749,8 +728,44 @@ key — surfaces as a `RuntimeError` that `auth/cookies.py` normalizes to
|
|
|
749
728
|
|
|
750
729
|
---
|
|
751
730
|
|
|
731
|
+
### Same profile can't be used in parallel
|
|
732
|
+
|
|
733
|
+
- **Status:** Mitigated (crash → typed fail-fast rejection) · **Severity:** Low · **Affects:** all versions
|
|
734
|
+
|
|
735
|
+
Chromium refuses to open two persistent contexts on the same `user-data-dir` simultaneously. Historically this surfaced as an unhelpful Chromium "ProcessSingleton: profile is locked" error partway through a run. As of the profile-lease hardening (production-readiness plan, slice D1/D3), gflow-cli enforces this itself: a cross-process advisory lock (`ProfileLease`, kernel `flock` on POSIX / `msvcrt.locking` on Windows) guards every profile directory. A second `gflow` invocation, `gflow serve` daemon task, or MCP call against an already-leased profile is rejected **immediately** — before any Chrome process starts — with a typed `ProfileLockedError` (**exit code 11**); it never waits and never silently corrupts the profile.
|
|
736
|
+
|
|
737
|
+
**Workaround:** use different profiles for parallel work — different profiles acquire independent leases and run fully concurrently.
|
|
738
|
+
|
|
739
|
+
```bash
|
|
740
|
+
# Terminal 1
|
|
741
|
+
gflow image batch ./batch-a.tsv --profile work
|
|
742
|
+
|
|
743
|
+
# Terminal 2 — different profile, same time, OK
|
|
744
|
+
gflow image batch ./batch-b.tsv --profile personal
|
|
745
|
+
```
|
|
746
|
+
|
|
747
|
+
**Roadmap:** Phase 4 (v0.4.0a2) added a per-worker Page pool on one shared BrowserContext (`GFLOW_CLI_CONCURRENCY=N`), intended to let one `gflow-cli` process fan out multiple in-flight generations, but no current CLI command drives more than one generation at a time through it — the only feature that did (a manifest-driven video batch runner) never worked and was removed. Cross-process same-profile serialization remains a hard constraint (Chromium can only own one persistent context per `user-data-dir`) — but it is now a clean, typed, fail-fast rejection instead of an unstructured crash. Multiple shells against the same profile remains a "use different profiles" workaround; there is no queueing/waiting mode.
|
|
748
|
+
|
|
749
|
+
---
|
|
750
|
+
|
|
752
751
|
## Resolved
|
|
753
752
|
|
|
753
|
+
### `gflow video`'s manifest-driven batch subcommand didn't skip already-completed entries — RESOLVED as obsolete
|
|
754
|
+
|
|
755
|
+
- **Status:** Resolved (obsolete) · **Severity:** Was-Medium · **Was-affecting:** v0.2.0a1 through the command's removal · **Fixed in:** n/a — removed in production-readiness hardening (see `fix: remove nonfunctional video batch command`)
|
|
756
|
+
|
|
757
|
+
This entry described a gap in `gflow video`'s `batch` subcommand: it never
|
|
758
|
+
maintained a local manifest-of-outputs, so rerunning a partially completed
|
|
759
|
+
TSV manifest after a mid-run failure would re-submit already-rendered rows
|
|
760
|
+
and could burn additional credits. The command itself, however, never
|
|
761
|
+
actually worked end-to-end — it always exited with a stub error before
|
|
762
|
+
reaching Flow — so no run could have been "partially completed" in the
|
|
763
|
+
first place. It has since been removed entirely as a nonfunctional stub.
|
|
764
|
+
The underlying command no longer exists, so this gap is moot rather than
|
|
765
|
+
fixed; kept here for searchability. `gflow image batch` (the real, working
|
|
766
|
+
batch command) is unaffected. For video, loop `gflow video t2v`/`i2v` from
|
|
767
|
+
the shell — see [`docs/USAGE.md` § Batch video generation (shell loop)](docs/USAGE.md#batch-video-generation-shell-loop).
|
|
768
|
+
|
|
754
769
|
### False "forced agentic — not recoverable" aborts from an icon-heuristic cohort probe
|
|
755
770
|
|
|
756
771
|
- **Status:** Resolved · **Severity:** Was-Medium (spurious exit-25 aborts on profiles that could in fact reach classic mode) · **Was-affecting:** `--ui-mode classic` and classic-only operations through v0.37.0 · **Fixed in:** 0.38.0 · **Tracked:** [#299](https://github.com/ffroliva/gflow-cli/issues/299), [#332](https://github.com/ffroliva/gflow-cli/issues/332)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: gflow-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.41.0
|
|
4
4
|
Summary: Unofficial CLI for Google Flow — drive Veo image-to-video generations from the terminal.
|
|
5
5
|
Project-URL: Homepage, https://github.com/ffroliva/gflow-cli
|
|
6
6
|
Project-URL: Issues, https://github.com/ffroliva/gflow-cli/issues
|
|
@@ -58,7 +58,7 @@ Requires-Dist: numpy>=1.24; extra == 'dev'
|
|
|
58
58
|
Requires-Dist: pyright>=1.1.0; extra == 'dev'
|
|
59
59
|
Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
|
|
60
60
|
Requires-Dist: pytest>=8.0.0; extra == 'dev'
|
|
61
|
-
Requires-Dist: ruff==0.15.
|
|
61
|
+
Requires-Dist: ruff==0.15.22; extra == 'dev'
|
|
62
62
|
Provides-Extra: gcs
|
|
63
63
|
Requires-Dist: gcsfs>=2024.2.0; extra == 'gcs'
|
|
64
64
|
Requires-Dist: universal-pathlib>=0.2.5; extra == 'gcs'
|
|
@@ -175,7 +175,7 @@ Onboard any agent in one line. Paste this into your agent of choice:
|
|
|
175
175
|
```text
|
|
176
176
|
gflow CLI → Provider (interchangeable) → Flow (ui_automation) / Mock (tests) / [planned: Official Veo]
|
|
177
177
|
↓
|
|
178
|
-
Playwright Chromium (headed login,
|
|
178
|
+
Playwright Chromium (headed — login AND generation, by default)
|
|
179
179
|
↓
|
|
180
180
|
aisandbox-pa.googleapis.com (Google's private Flow API)
|
|
181
181
|
```
|
|
@@ -188,7 +188,7 @@ gflow CLI → Provider (interchangeable) → Flow (ui_automation) / Mock (te
|
|
|
188
188
|
|
|
189
189
|
## Project status
|
|
190
190
|
|
|
191
|
-
**Alpha.** Image (t2i, i2i, upload, upscale, batch) and video (t2v, i2v, r2v,
|
|
191
|
+
**Alpha.** Image (t2i, i2i, upload, upscale, batch) and video (t2v, i2v, r2v, chain) run end-to-end on `ui_automation`, with a 5-model Veo picker plus `--duration` and `--count`. Beyond single generations: `gflow movie` renders multi-scene manifests, `gflow instructions` manages persistent Agent-Mode brief cards (credits-free), `gflow character` handles reusable subjects, `gflow scene` does credit-free server-side stitching, `--tool` applies prompt-rewriting tools, and an MCP server (`gflow mcp run` stdio / `gflow serve` HTTP-SSE) exposes the core surface to AI agents with a CI-enforced CLI↔MCP parity contract.
|
|
192
192
|
|
|
193
193
|
Full milestone history lives in [CHANGELOG.md](CHANGELOG.md). Where the project is heading: [ROADMAP.md](ROADMAP.md).
|
|
194
194
|
|
|
@@ -667,6 +667,8 @@ Records image, batch, T2V, I2V, and R2V provenance in a local SQLite catalog. Re
|
|
|
667
667
|
|
|
668
668
|
**2026-07-09 verification — the current stealth fix is CONFIRMED SUFFICIENT (so this stays parked).** A 20-generation baseline on a live authed profile through the default stealth stack produced a **0.0% WAF 403 rate** (19/20 success; the one miss was a UI-scrape timeout, not a WAF block). This met ADR-13's "must verify before implementing" gate and closed the [Camoufox adoption roadmap](superpowers/plans/2026-07-09-camoufox-adoption/PLAN.md) at Phase 2 — the Camoufox engine was NOT built. Evidence: [superpowers/spikes/2026-07-09-camoufox-waf-403.md](superpowers/spikes/2026-07-09-camoufox-waf-403.md). Re-run `scripts/spike_waf_camoufox.py` if a repeatable WAF-403 is later observed; a materially non-zero rate would reopen CDP-Attach / Camoufox.
|
|
669
669
|
|
|
670
|
+
**2026-07-19 — packaged CDP lifecycle removed.** The unused CDP attach/spawn lockfile lifecycle that previously shipped in `browser_manager.py` (`get_or_launch_browser` / `close_browser` and its port/lockfile/singleton-lock helpers) was deleted: zero production consumers, an unsafe no-lock attach-to-any-Chrome path, and no positive evidence outweighing the 2026-05-12 WAF rejection above. Chrome discovery/channel helpers (`is_chrome_available`, `channel_for_profile`, etc.) — used by the real auth/UI-automation path — were kept. This ADR's "parked" status is unchanged: CDP-attach as a distinct opt-in transport remains a backlog idea for a future contributor with a safe ownership model; see `.superpowers/sdd/cdp-decision.md` for the evidence.
|
|
671
|
+
|
|
670
672
|
---
|
|
671
673
|
|
|
672
674
|
### Phase 8 — Pluggable storage backend — BACKLOG
|
|
@@ -104,7 +104,7 @@ Onboard any agent in one line. Paste this into your agent of choice:
|
|
|
104
104
|
```text
|
|
105
105
|
gflow CLI → Provider (interchangeable) → Flow (ui_automation) / Mock (tests) / [planned: Official Veo]
|
|
106
106
|
↓
|
|
107
|
-
Playwright Chromium (headed login,
|
|
107
|
+
Playwright Chromium (headed — login AND generation, by default)
|
|
108
108
|
↓
|
|
109
109
|
aisandbox-pa.googleapis.com (Google's private Flow API)
|
|
110
110
|
```
|
|
@@ -117,7 +117,7 @@ gflow CLI → Provider (interchangeable) → Flow (ui_automation) / Mock (te
|
|
|
117
117
|
|
|
118
118
|
## Project status
|
|
119
119
|
|
|
120
|
-
**Alpha.** Image (t2i, i2i, upload, upscale, batch) and video (t2v, i2v, r2v,
|
|
120
|
+
**Alpha.** Image (t2i, i2i, upload, upscale, batch) and video (t2v, i2v, r2v, chain) run end-to-end on `ui_automation`, with a 5-model Veo picker plus `--duration` and `--count`. Beyond single generations: `gflow movie` renders multi-scene manifests, `gflow instructions` manages persistent Agent-Mode brief cards (credits-free), `gflow character` handles reusable subjects, `gflow scene` does credit-free server-side stitching, `--tool` applies prompt-rewriting tools, and an MCP server (`gflow mcp run` stdio / `gflow serve` HTTP-SSE) exposes the core surface to AI agents with a CI-enforced CLI↔MCP parity contract.
|
|
121
121
|
|
|
122
122
|
Full milestone history lives in [CHANGELOG.md](CHANGELOG.md). Where the project is heading: [ROADMAP.md](ROADMAP.md).
|
|
123
123
|
|
|
@@ -283,10 +283,10 @@ def generate(prompt: str) -> None:
|
|
|
283
283
|
## Concurrency model (shipped, Phase 4 / v0.4.0a2)
|
|
284
284
|
|
|
285
285
|
- **Single-process, single-event-loop** (`asyncio`). No multiprocessing, no application-level threads (only what Playwright uses internally).
|
|
286
|
-
- **
|
|
286
|
+
- **Page pool:** `FlowApiClient.__aenter__` opens `Settings.concurrency` Playwright Pages inside **one shared persistent `BrowserContext`**. Operations check out a Page via an `asyncio.Queue` (FIFO, bounded by `maxsize=N`); a double-checkin raises `QueueFull` loudly rather than corrupting the pool. See `gflow_cli.api.client.FlowApiClient._checkout_page` / `_checkin_page`. **No current CLI command drives more than one generation concurrently through this pool** — the one caller that used to fan out manifest entries via `asyncio.gather` (a manifest-driven video batch runner) never worked end-to-end and was removed as a nonfunctional stub; `gflow image batch` processes its manifest sequentially.
|
|
287
287
|
- **Across profiles:** parallelism by spawning one shell per profile. Chromium refuses two persistent contexts on the same `user-data-dir`, so cross-profile parallelism is a process-level concern, not a coroutine one. See [KNOWN_ISSUES § Same profile can't be used in parallel](../KNOWN_ISSUES.md#same-profile-cant-be-used-in-parallel).
|
|
288
288
|
- **Why a Page pool and not a `Semaphore`?** A semaphore over a single shared Page would serialize at `page.request.post` anyway (Playwright doesn't make a Page thread-safe). N Pages inside one Context let Chromium pipeline the requests while still sharing the auth cookies. T0 of the Phase 4 spike measured ~45 ms per Page creation at N=16 — well under the 200 ms/Page threshold.
|
|
289
|
-
- **What's backlog (post-v0.5):** account-pool aware scheduling across multiple signed-in profiles (round-robin), and a separate-process driver so two
|
|
289
|
+
- **What's backlog (post-v0.5):** a concurrent caller that actually exercises the Page pool above `N=1`, account-pool aware scheduling across multiple signed-in profiles (round-robin), and a separate-process driver so two concurrent invocations against the same profile can serialize properly via OS file lock.
|
|
290
290
|
|
|
291
291
|
## Observability (shipped, Phase 4 / v0.4.0a2)
|
|
292
292
|
|
|
@@ -36,14 +36,17 @@ This page documents the full lifecycle: capture, storage, reuse, refresh, multi-
|
|
|
36
36
|
└────────────┬─────────────────────────┘
|
|
37
37
|
│
|
|
38
38
|
▼
|
|
39
|
-
$ gflow image t2i ... (later,
|
|
39
|
+
$ gflow image t2i ... (later, headed by default)
|
|
40
40
|
│
|
|
41
41
|
▼
|
|
42
42
|
┌──────────────────────────────────────┐
|
|
43
|
-
│ Playwright launches
|
|
44
|
-
│
|
|
45
|
-
│
|
|
46
|
-
│
|
|
43
|
+
│ Playwright launches HEADED Chrome │
|
|
44
|
+
│ with the same profile dir (the │
|
|
45
|
+
│ production default — reCAPTCHA │
|
|
46
|
+
│ Enterprise rejects headless outright│
|
|
47
|
+
│ with a 403); page.request.post(...) │
|
|
48
|
+
│ auto-sends cookies. No token │
|
|
49
|
+
│ plumbing needed. │
|
|
47
50
|
└──────────────────────────────────────┘
|
|
48
51
|
```
|
|
49
52
|
|
|
@@ -342,9 +345,9 @@ gflow image t2i "test" --profile personal
|
|
|
342
345
|
gflow image t2i "client work" --profile client-a
|
|
343
346
|
```
|
|
344
347
|
|
|
345
|
-
Each profile is fully isolated (its own cookies, its own Flow project history).
|
|
348
|
+
Each profile is fully isolated (its own cookies, its own Flow project history). **Different profiles run fully in parallel** — each acquires its own cross-process `ProfileLease` on its own canonical directory, so concurrent `gflow` calls across profiles never contend. **The same profile can only ever have one active holder.** A cross-process advisory lock (`ProfileLease`, kernel `flock`/`msvcrt.locking`) enforces this fail-fast: a second call against an already-leased profile — whether it's another `gflow` invocation, the `gflow serve` daemon, or an MCP tool call — is rejected immediately with `ProfileLockedError` (exit code 11); it never blocks or waits for the lease to free up.
|
|
346
349
|
|
|
347
|
-
For automated multi-account
|
|
350
|
+
For automated multi-account work: a per-profile Page pool (`GFLOW_CLI_CONCURRENCY=N`, 1–16, shipped in v0.4.0a2) opens N Playwright Pages on one shared BrowserContext within a single profile, but no current CLI command drives more than one generation concurrently through it — the one caller that used to (a manifest-driven video batch runner) never worked and was removed. Cross-profile parallel runs remain "one shell per profile"; same-profile contention is a fast, typed rejection rather than a Chromium crash (see [KNOWN_ISSUES § Same profile can't be used in parallel](../KNOWN_ISSUES.md#same-profile-cant-be-used-in-parallel)).
|
|
348
351
|
|
|
349
352
|
## Refresh / expiry
|
|
350
353
|
|
|
@@ -400,7 +403,7 @@ For deeper guidance see [SECURITY.md](SECURITY.md).
|
|
|
400
403
|
## FAQ
|
|
401
404
|
|
|
402
405
|
**Q: Can I use `gflow-cli` without a browser at all?**
|
|
403
|
-
A:
|
|
406
|
+
A: No — not for `auth login`, and not for generation either. `auth login` needs Chromium so you can solve any 2FA/CAPTCHA challenge interactively. Generation calls also launch a real, **headed** Chrome window by default (`GFLOW_CLI_HEADLESS=false`) — the `ui_automation` transport is gflow-cli's only production transport, and reCAPTCHA Enterprise rejects headless Chromium with an immediate 403, so there is no way to run production generation on a display-less machine without a virtual display (e.g. Xvfb) or a workstation. Plan for that when choosing where to run gflow-cli long-term; see [CONFIGURATION.md § `GFLOW_CLI_HEADLESS`](CONFIGURATION.md#gflow_cli_headless).
|
|
404
407
|
|
|
405
408
|
**Q: Does this support Google Workspace SSO?**
|
|
406
409
|
A: Yes — sign in normally during `auth login`. Whatever your IdP flow looks like in the browser, that's what you'll go through. The captured cookies are the same.
|
|
@@ -178,10 +178,10 @@ GFLOW_CLI_AUTH_LOGIN_TIMEOUT=120 gflow auth login # abort after 2 minutes
|
|
|
178
178
|
|
|
179
179
|
### `GFLOW_CLI_CONCURRENCY`
|
|
180
180
|
|
|
181
|
-
**What:** Per-worker Playwright Page-pool size
|
|
181
|
+
**What:** Per-worker Playwright Page-pool size. `FlowApiClient.__aenter__` opens N Pages inside one shared persistent BrowserContext; operations check out a Page via an `asyncio.Queue` (FIFO, bounded by `maxsize=N`). No current CLI command fans out multiple generations concurrently through this pool — `gflow image batch` processes prompts sequentially, and the manifest-driven video runner that used to fan out via `asyncio.gather` was removed as nonfunctional — so raising this above `1` has no effect until a concurrent caller exists.
|
|
182
182
|
**Values:** `1`–`16`
|
|
183
183
|
**Default:** `1` (no fan-out)
|
|
184
|
-
**Recommended starting point:** `
|
|
184
|
+
**Recommended starting point:** `1` until a concurrent caller lands. Each additional Page would cost ~30–60 MiB of memory on Chromium headless; don't exceed `8` without measuring resident-set size. Cookies and storage state are shared at Context level, so every Page would inherit the signed-in profile for free.
|
|
185
185
|
**Shipped in:** v0.4.0a2.
|
|
186
186
|
|
|
187
187
|
### `GFLOW_CLI_DB_PATH`
|
|
@@ -218,8 +218,8 @@ GFLOW_CLI_HISTORY_PROMPTS=redacted gflow image t2i "confidential brief"
|
|
|
218
218
|
|
|
219
219
|
**What:** Run Playwright in headless mode for non-`auth login` commands.
|
|
220
220
|
**Values:** `true` | `false`
|
|
221
|
-
**Default:** `true`
|
|
222
|
-
**
|
|
221
|
+
**Default:** `false` — **headed real Chrome is the production default**, not an opt-in fallback. The `ui_automation` transport (gflow-cli's only production transport) requires a headed browser: reCAPTCHA Enterprise rejects headless Chromium with an immediate 403, so `headless=true` is not a WAF workaround — it only exists for CI/CD environments running a non-`ui_automation` transport (e.g. `bearer`/`sapisidhash`, experimental).
|
|
222
|
+
**WAF-sensitive runs:** set `GFLOW_CLI_HEADLESS=false` explicitly (it is already the default, but pin it in CI/CD env files or scripts that also set `headless=true` for a different transport, so a transport switch back to `ui_automation` doesn't silently regress to a rejected headless launch).
|
|
223
223
|
|
|
224
224
|
### `GFLOW_CLI_BROWSER_ENGINE`
|
|
225
225
|
|
|
@@ -311,8 +311,8 @@ gflow image t2i "..." --out ./shots/
|
|
|
311
311
|
# Video: --out-dir is a directory for the generated mp4
|
|
312
312
|
gflow video t2v "..." --out-dir ./out/
|
|
313
313
|
|
|
314
|
-
#
|
|
315
|
-
gflow
|
|
314
|
+
# Image batch: --out overrides the images/<date>/ root
|
|
315
|
+
gflow image batch ./manifest.tsv --out ./batch-out/
|
|
316
316
|
|
|
317
317
|
# Video chain: --out-dir holds the per-link mp4s + seed frames
|
|
318
318
|
gflow video chain ./story.jsonl --out-dir ./chain-out/ --yes
|
|
@@ -397,7 +397,7 @@ See [EXTERNAL_STORAGE.md](EXTERNAL_STORAGE.md) for MinIO and GCS examples.
|
|
|
397
397
|
```bash
|
|
398
398
|
GFLOW_CLI_LOG_FORMAT=json \
|
|
399
399
|
GFLOW_CLI_TIMEOUT_SECONDS=300 \
|
|
400
|
-
gflow
|
|
400
|
+
gflow image batch ./manifest.tsv
|
|
401
401
|
```
|
|
402
402
|
|
|
403
403
|
### "I want to test against the official Veo SDK"
|
|
@@ -426,4 +426,4 @@ gflow image t2i "test idea" --profile experiments
|
|
|
426
426
|
| `FileNotFoundError: $GFLOW_CLI_HOME/profile_default not found` | First run, no auth yet | `gflow auth login` |
|
|
427
427
|
| `AuthExpiredError` | Cookies expired or revoked | `gflow auth login --profile <name>` |
|
|
428
428
|
| Output files don't appear where I expect | Flag > env > .env > default — check actual resolved path | `gflow image t2i ... --verbose` shows the resolved output path |
|
|
429
|
-
| Two concurrent calls
|
|
429
|
+
| `ProfileLockedError` (exit code 11) | Two concurrent calls against the same profile — the cross-process `ProfileLease` fails fast (never waits) on same-profile contention, whether the second holder is another `gflow` process, the `gflow serve` daemon, or an MCP call | Wait for the first call to finish, or use `--profile other` — different profiles run fully in parallel, each with its own lease |
|