gflow-cli 0.52.0__tar.gz → 0.53.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.52.0 → gflow_cli-0.53.0}/.codex-plugin/plugin.json +1 -1
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/AGENTS.md +1 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/CHANGELOG.md +12 -1
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/PKG-INFO +1 -1
- gflow_cli-0.53.0/docs/LIVE_VERIFICATION_v0.52.0.md +55 -0
- gflow_cli-0.53.0/docs/superpowers/plans/2026-08-06-driver-delay-jittering/PLAN.md +93 -0
- gflow_cli-0.53.0/docs/superpowers/plans/2026-08-06-driver-delay-jittering/SCENARIO.md +26 -0
- gflow_cli-0.53.0/docs/superpowers/plans/2026-08-06-overlay-changelog-watermark/PLAN.md +94 -0
- gflow_cli-0.53.0/docs/superpowers/plans/2026-08-06-overlay-changelog-watermark/SCENARIO.md +46 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/pyproject.toml +1 -1
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/skills/pr-council-review/SKILL.md +1 -1
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/skills/predict/SKILL.md +1 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/skills/scenario/SKILL.md +2 -2
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/__init__.py +1 -1
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/api/transports/ui_automation.py +36 -12
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/api/transports/test_ui_automation.py +61 -8
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/uv.lock +1 -1
- gflow_cli-0.52.0/docs/LIVE_VERIFICATION_v0.52.0.md +0 -41
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/.agents/plugins/marketplace.json +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/.claude/README.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/.claude/commands/gflow/active.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/.claude/commands/gflow/branch-review.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/.claude/commands/gflow/changelog.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/.claude/commands/gflow/check.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/.claude/commands/gflow/doc-review.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/.claude/commands/gflow/issue-assessment.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/.claude/commands/gflow/issue-resolve.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/.claude/commands/gflow/known-issues.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/.claude/commands/gflow/live-verify.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/.claude/commands/gflow/llm-council.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/.claude/commands/gflow/next.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/.claude/commands/gflow/plan.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/.claude/commands/gflow/pr-council-review.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/.claude/commands/gflow/predict.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/.claude/commands/gflow/release.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/.claude/commands/gflow/scenario.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/.claude/commands/gflow/sonar.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/.claude/commands/gflow/status.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/.env.template +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/.gitattributes +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/.github/CODEOWNERS +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/.github/copilot-instructions.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/.github/dependabot.yml +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/.github/workflows/ci.yml +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/.github/workflows/deps-watch.yml +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/.github/workflows/external-pr-triage.yml +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/.github/workflows/governance-advisory.yml +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/.github/workflows/governance-benchmark.yml +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/.github/workflows/labels.yml +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/.github/workflows/main-base-guard.yml +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/.github/workflows/pages.yml +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/.github/workflows/release.yml +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/.gitignore +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/.gitleaks.toml +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/.pre-commit-config.yaml +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/.secrets.baseline +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/CLAUDE.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/CONFIGURATION.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/CONTRIBUTING.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/DISCLAIMER.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/KNOWN_ISSUES.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/LICENSE +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/PLAN.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/README.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/RELEASE.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/ROADMAP.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/conftest.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/deploy/PR-TRIAGE-AUTOPILOT-OPS.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docker-compose.yml +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/AGENT_GUIDE.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/AGENT_UI_E2E.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/AGENT_UI_RECON.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/ARCHITECTURE.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/ASSET_TAGGING_RECON.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/AUTHENTICATION.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/CHARACTER.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/CHARACTER_RECON.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/CONFIGURATION.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/DATA_LAYER.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/DEBUGGING.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/DEMOS.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/DEVELOPMENT.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/E2E_TESTING.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/EXTERNAL_STORAGE.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/GITHUB.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/GOVERNANCE_BENCHMARK.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/IMAGE_UPSCALE_RECON.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/INDEX.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/INSTRUCTIONS.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/LIVE_VERIFICATION_data_layer.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/LIVE_VERIFICATION_image_batch.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/LIVE_VERIFICATION_playwright_1.61.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/LIVE_VERIFICATION_v0.10.0.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/LIVE_VERIFICATION_v0.11.0.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/LIVE_VERIFICATION_v0.12.0.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/LIVE_VERIFICATION_v0.13.0.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/LIVE_VERIFICATION_v0.16.0.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/LIVE_VERIFICATION_v0.17.0.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/LIVE_VERIFICATION_v0.18.0.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/LIVE_VERIFICATION_v0.19.0.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/LIVE_VERIFICATION_v0.20.0.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/LIVE_VERIFICATION_v0.20.1.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/LIVE_VERIFICATION_v0.21.0.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/LIVE_VERIFICATION_v0.22.0.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/LIVE_VERIFICATION_v0.23.0.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/LIVE_VERIFICATION_v0.24.0.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/LIVE_VERIFICATION_v0.25.0.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/LIVE_VERIFICATION_v0.26.0.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/LIVE_VERIFICATION_v0.27.0.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/LIVE_VERIFICATION_v0.27.1.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/LIVE_VERIFICATION_v0.28.0.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/LIVE_VERIFICATION_v0.29.0.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/LIVE_VERIFICATION_v0.30.0.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/LIVE_VERIFICATION_v0.31.0.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/LIVE_VERIFICATION_v0.32.0.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/LIVE_VERIFICATION_v0.32.1.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/LIVE_VERIFICATION_v0.33.0.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/LIVE_VERIFICATION_v0.34.0.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/LIVE_VERIFICATION_v0.35.0.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/LIVE_VERIFICATION_v0.36.0.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/LIVE_VERIFICATION_v0.37.0.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/LIVE_VERIFICATION_v0.38.0.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/LIVE_VERIFICATION_v0.38.1.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/LIVE_VERIFICATION_v0.39.0.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/LIVE_VERIFICATION_v0.40.0-production-readiness.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/LIVE_VERIFICATION_v0.40.0.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/LIVE_VERIFICATION_v0.41.0.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/LIVE_VERIFICATION_v0.42.0.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/LIVE_VERIFICATION_v0.43.0.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/LIVE_VERIFICATION_v0.44.0.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/LIVE_VERIFICATION_v0.45.0.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/LIVE_VERIFICATION_v0.46.0.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/LIVE_VERIFICATION_v0.46.1.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/LIVE_VERIFICATION_v0.47.0.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/LIVE_VERIFICATION_v0.48.0.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/LIVE_VERIFICATION_v0.49.0.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/LIVE_VERIFICATION_v0.50.0.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/LIVE_VERIFICATION_v0.51.0.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/LIVE_VERIFICATION_v0.7.0.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/LIVE_VERIFICATION_v0.8.1.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/LIVE_VERIFICATION_v0.9.0.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/LIVE_VERIFICATION_v0.9.1.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/LIVE_VERIFICATION_video_download.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/MCP.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/MOVIE.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/PROJECT_STATUS.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/PROMPT_EXPANSION.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/REFERENCE_STRATEGIES.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/SECURITY.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/TOOLS.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/USAGE.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/USER_GUIDE.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/assets/demo-split-pf.gif +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/assets/example-run.gif +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/assets/examples.webp +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/medium_tutorial.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/schemas/movie-handoff.schema.json +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/sonar-cleanup-tracker.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/superpowers/plans/2026-06-12-issue-174-library-ui-attach/PLAN.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/superpowers/plans/2026-06-22-mcp-server/PLAN.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/superpowers/plans/2026-06-22-mcp-server/PREDICT.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/superpowers/plans/2026-06-22-mcp-server/SCENARIO.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/superpowers/plans/2026-06-22-prompt-expansion/PLAN.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/superpowers/plans/2026-06-22-prompt-expansion/PREDICT.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/superpowers/plans/2026-06-22-prompt-expansion/SCENARIO.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/superpowers/plans/2026-06-24-gflow-studio-scaffold/PLAN.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/superpowers/plans/2026-06-24-rest-api-layer/PLAN.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/superpowers/plans/2026-06-26-mcp-e2e-test/PLAN.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/superpowers/plans/2026-07-08-pr-triage-autopilot/PLAN.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/superpowers/plans/2026-07-09-camoufox-adoption/PLAN.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/superpowers/plans/2026-07-14-storyboarding-and-visual-curation/PLAN.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/superpowers/plans/2026-07-18-asset-tagging/PLAN.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/superpowers/plans/2026-07-19-live-verify/PLAN.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/superpowers/plans/2026-07-19-production-readiness-browser-lifecycle.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/superpowers/plans/2026-07-19-production-readiness-driver-cdp-verification.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/superpowers/plans/2026-07-19-production-readiness-public-truth.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/superpowers/plans/2026-07-19-production-readiness-queue-safety.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/superpowers/plans/2026-07-26-character-prompt-polishing/PLAN.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/superpowers/plans/2026-07-26-project-name-management/PLAN.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/superpowers/plans/2026-07-26-self-documenting-errors/PLAN.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/superpowers/plans/2026-07-27-overlay-banner-dismissal/PLAN.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/superpowers/plans/2026-07-27-tier-aware-credit-confirmations/PLAN.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/superpowers/plans/2026-07-27-tier-aware-credit-confirmations/SCENARIO.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/superpowers/plans/2026-08-04-mcp-tasks/PLAN.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/superpowers/plans/2026-08-04-output-hardening/PLAN.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/superpowers/plans/2026-08-05-issue-317-intra-batch-references/PLAN.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/superpowers/plans/2026-08-05-issue-317-intra-batch-references/SCENARIO.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/superpowers/plans/2026-08-05-issue-402-entity-provenance/PLAN.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/superpowers/plans/2026-08-05-issue-402-entity-provenance/SCENARIO.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/superpowers/plans/2026-08-05-issue-451-duration-tab-drift/PLAN.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/superpowers/plans/2026-08-05-issue-451-duration-tab-drift/SCENARIO.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/superpowers/research/2026-06-27-tool-abstraction-evaluation.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/superpowers/specs/2026-06-29-issue-assessment-workflow-design.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/superpowers/specs/2026-07-04-pr-triage-autopilot-design.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/superpowers/specs/2026-07-18-asset-tagging-design.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/superpowers/specs/2026-07-19-live-verify-design.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/superpowers/specs/2026-07-19-production-readiness-hardening-design.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/superpowers/spikes/2026-07-09-camoufox-waf-403.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/superpowers/spikes/2026-07-12-ui-cohort-backend-config.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/superpowers/spikes/2026-07-17-production-readiness-assessment.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/docs/superpowers/spikes/2026-08-01-mcp-2026-07-28-spec-impact.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/eval/pr_triage_eval.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/eval/pr_triage_fixtures.json +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/examples/README.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/examples/batch_from_config.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/examples/multi_prompt_t2i.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/examples/sample_config.json +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/examples/sample_prompts.txt +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/examples/single_image_t2i.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/examples/workflow_chain.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/index.html +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/llms.txt +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/samples/README.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/samples/captured/01_upload_image.json +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/samples/captured/02_batchAsyncGenerateVideoText.json +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/samples/captured/03_batchCheckAsyncVideoGenerationStatus.json +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/samples/captured/04_archive_workflow.json +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/samples/captured/05_createProject.json +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/samples/captured/06_batchGenerateImages.json +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/samples/captured/07_batchGenerateImages_seeded.json +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/samples/captured/08_batchAsyncGenerateVideoStartAndEndImage.json +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/samples/captured/09_batchAsyncGenerateVideoReferenceImages.json +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/samples/captured/10_batchCheckAsyncVideoGenerationStatus_successful.json +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/samples/captured/11_batchCheckAsyncVideoGenerationStatus_failed.json +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/samples/captured/12_create_scene.json +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/samples/captured/13_sceneWorkflows_update.json +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/samples/captured/14_get_scene_workflows.json +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/samples/captured/15_commit_flowWorkflow.json +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/scripts/autopilot/Dockerfile.triage +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/scripts/autopilot/entrypoint.sh +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/scripts/autopilot/pr_triage_autopilot.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/scripts/autopilot/pr_triage_gate.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/scripts/autopilot/run_sandboxed_review.sh +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/scripts/ci/check_doc_links.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/scripts/ci/check_materiality.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/scripts/ci/check_release_artifacts.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/scripts/ci/check_repo_hygiene.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/scripts/ci/check_website_docs_pii.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/scripts/ci/generate_website_docs.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/scripts/debug_editor.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/scripts/debug_gen_settings.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/scripts/debug_settings.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/scripts/dev/_recording_client.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/scripts/dev/_spike_common.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/scripts/dev/active_plan.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/scripts/dev/analyze_agent_ui_capture.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/scripts/dev/capture_i2v_frame_slots_dom.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/scripts/dev/capture_i2v_intercept_submit.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/scripts/dev/capture_i2v_model_select_repro.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/scripts/dev/capture_i2v_post_bind_state.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/scripts/dev/capture_image_add_media_dom.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/scripts/dev/capture_locale_invariants.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/scripts/dev/cdp_drive_and_probe.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/scripts/dev/character_create_spike.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/scripts/dev/character_create_spike_v2.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/scripts/dev/dump_character_selectors.js +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/scripts/dev/incident_bundle_quality.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/scripts/dev/live_verify_mcp_tasks.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/scripts/dev/make_project.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/scripts/dev/materiality_backtest.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/scripts/dev/monitor_pr_38.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/scripts/dev/patch_character.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/scripts/dev/skillopt/README.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/scripts/dev/skillopt/harness.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/scripts/dev/skillopt/tasks.json +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/scripts/dev/sonar-local-scan.sh +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/scripts/dev/sonar-pre-push-gate.sh +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/scripts/dev/spike_char_editor_dom.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/scripts/dev/spike_char_gen_capture.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/scripts/dev/spike_character_prompt_format.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/scripts/dev/spike_image_upscale_capture.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/scripts/dev/spike_image_upscale_drive.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/scripts/dev/spike_image_upscale_recaptcha_action.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/scripts/dev/spike_image_upscale_rest_probe.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/scripts/dev/spike_incident_live.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/scripts/dev/spike_issue170_picker_locale_recon.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/scripts/dev/spike_issue174_library_ui_recon.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/scripts/dev/spike_issue313_agent_mode_controls.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/scripts/dev/spike_issue314_picker_filename_search.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/scripts/dev/spike_issue404_count_tabs_recon.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/scripts/dev/spike_mode_roundtrip.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/scripts/dev/spike_mode_switch_agentic_to_classic.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/scripts/dev/spike_movie_attach_payload.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/scripts/dev/spike_movie_entity_recon.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/scripts/dev/spike_movie_gen_capture.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/scripts/dev/spike_movie_picker_select.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/scripts/dev/spike_movie_voice_list.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/scripts/dev/spike_omni_flash_i2v_ui_recon.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/scripts/dev/spike_patch_entity.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/scripts/dev/spike_patchright.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/scripts/diag/README.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/scripts/diag/capture_flow_traffic.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/scripts/diag/memory_profile.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/scripts/diag/recaptcha_mint.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/scripts/diag/spike_387_openai_compat.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/scripts/e2e/agentic_image_e2e.ps1 +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/scripts/e2e/capture_agent_toggle.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/scripts/record_demo.ps1 +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/scripts/smoke_image.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/scripts/smoke_video_editor.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/scripts/smoke_worker_style.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/scripts/spike_waf_camoufox.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/scripts/verify_chrome_auth_viability.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/skills/README.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/skills/changelog/SKILL.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/skills/check/SKILL.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/skills/doc-review/SKILL.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/skills/gflow-cli/SKILL.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/skills/issue-assessment/SKILL.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/skills/issue-resolve/SKILL.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/skills/known-issues/SKILL.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/skills/live-verify/SKILL.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/skills/llm-council/SKILL.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/skills/plan/SKILL.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/skills/release/SKILL.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/skills/sonar/SKILL.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/skills/status/SKILL.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/sonar-project.properties +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/__main__.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/_cli_helpers.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/api/__init__.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/api/_engine.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/api/_retry.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/api/_sapisidhash.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/api/character.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/api/client.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/api/dto.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/api/image.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/api/image_upscale.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/api/recaptcha.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/api/routes.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/api/scene.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/api/transports/__init__.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/api/transports/_common.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/api/transports/_fingerprint.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/api/transports/base.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/api/transports/drivers/__init__.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/api/transports/drivers/agentic.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/api/transports/drivers/base.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/api/transports/drivers/classic.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/api/transports/drivers/factory.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/api/transports/experimental/__init__.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/api/transports/experimental/bearer.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/api/transports/experimental/evaluate_fetch.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/api/transports/experimental/sapisidhash.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/api/transports/mode_control.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/api/transports/ui_automation_video.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/api/video.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/auth/__init__.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/auth/base.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/auth/cookies.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/auth/factory.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/auth/internal_chromium.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/auth/real_chrome.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/auth/strategies.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/auth/verification.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/browser_manager.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/chain.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/chain_manifest.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/cli.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/cli_character.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/cli_data.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/cli_image.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/cli_instructions.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/cli_models.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/cli_movie.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/cli_project.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/cli_run.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/cli_scene.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/cli_tools.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/cli_video.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/composition.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/config.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/data/__init__.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/data/chain_repo.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/data/migrations/0001_initial.sql +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/data/migrations/0002_add_cloud_storage.sql +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/data/migrations/0003_add_scene_tables.sql +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/data/migrations/0004_add_scene_output_path.sql +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/data/migrations/0005_add_chain_links.sql +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/data/migrations/0006_add_operations_metadata.sql +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/data/migrations/0007_queue.sql +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/data/migrations/0008_add_operation_expanded_prompt.sql +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/data/migrations/0009_queue_claims.sql +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/data/migrations/__init__.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/data/models.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/data/queries.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/data/recorder.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/data/redaction.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/data/repository.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/data/store.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/diagnostics.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/errors.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/exceptions.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/image_batch.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/json_output.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/mcp/__init__.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/mcp/prompts.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/mcp/resources.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/mcp/server.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/mcp/tasks_extension.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/mcp/tools.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/media.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/movie_manifest.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/observability.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/paths.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/profile_lease.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/profile_store.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/redaction.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/services/__init__.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/services/character_create.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/services/mentions.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/storage.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/tools/__init__.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/tools/banned.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/tools/builtin/__init__.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/tools/builtin/creative-director.toml +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/tools/builtin/reverse-engineer.toml +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/tools/builtin/storyboard.toml +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/tools/expander.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/tools/invocation.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/tools/loader.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/tools/registry.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/tools/runtime.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/tools/spec.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/ui/app.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/ui/server.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/worker/codec.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/worker/daemon.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/src/gflow_cli/worker/queue.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tasks/lessons.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/test_assets/sample_batch.json +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/test_assets/sample_batch.tsv +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/test_assets/sample_batch_invalid.tsv +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/__init__.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/api/__init__.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/api/fixtures/character_gen_response.json +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/api/fixtures/patch_entity_response.json +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/api/test_aisandbox_auth_error.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/api/test_aisandbox_auth_headers.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/api/test_bearer_redaction.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/api/test_character.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/api/test_client.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/api/test_client_character.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/api/test_client_delete_characters.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/api/test_client_errors.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/api/test_client_generate_character.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/api/test_client_image.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/api/test_client_incidents.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/api/test_client_launch_kwargs.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/api/test_client_patch_entity.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/api/test_client_scene.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/api/test_client_upscale.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/api/test_concurrency.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/api/test_dto.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/api/test_engine.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/api/test_image.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/api/test_image_dto.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/api/test_image_upscale.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/api/test_post_json_aisandbox_auth.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/api/test_recaptcha.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/api/test_retry.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/api/test_routes.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/api/test_routes_character.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/api/test_routes_scene.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/api/test_sapisidhash_helper.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/api/test_scene_models.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/api/test_video.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/api/test_video_request.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/api/transports/__init__.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/api/transports/conftest.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/api/transports/drivers/__init__.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/api/transports/drivers/test_agentic.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/api/transports/drivers/test_classic.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/api/transports/drivers/test_factory.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/api/transports/drivers/test_ui_mode.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/api/transports/test_agentic_cohort_detection.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/api/transports/test_base.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/api/transports/test_bearer.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/api/transports/test_common.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/api/transports/test_evaluate_fetch.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/api/transports/test_factory.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/api/transports/test_fingerprint.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/api/transports/test_mode_control.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/api/transports/test_sapisidhash.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/api/transports/test_selector_symmetry.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/api/transports/test_transport_timeout.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/api/transports/test_ui_automation_batch.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/api/transports/test_ui_automation_image_mode.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/api/transports/test_ui_automation_video.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/api/transports/test_ui_character_editor.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/auth/strategies/test_factory.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/auth/strategies/test_strategies.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/auth/test_cookies.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/auth/test_real_chrome.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/auth/test_verification.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/autopilot/test_pr_triage_autopilot.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/cli/__init__.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/cli/test_cli_auth_list.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/cli/test_cli_character.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/cli/test_cli_character_create.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/cli/test_cli_data.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/cli/test_cli_data_errors.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/cli/test_cli_data_errors_retention.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/cli/test_cli_image.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/cli/test_cli_image_seed_removed.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/cli/test_cli_image_selector_drift.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/cli/test_cli_image_upscale.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/cli/test_cli_image_uuid_ref_enrichment.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/cli/test_cli_instructions.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/cli/test_cli_models.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/cli/test_cli_movie.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/cli/test_cli_run.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/cli/test_cli_scene.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/cli/test_cli_tools.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/cli/test_cli_video.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/cli/test_cli_video_chain.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/cli/test_error_handling.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/cli/test_failure_funnel.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/cli/test_helpers.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/cli/test_incident_output.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/cli/test_movie_manifest.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/cli/test_movie_manifest_style_variants.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/cli/test_predictable_output.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/cli/test_settings_validation.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/cli/test_t2i_multi_prompt.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/composition/test_character.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/composition/test_compose_prompt.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/composition/test_handoff.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/composition/test_style_variants.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/composition/test_style_variants_e2e.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/conftest.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/data/__init__.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/data/test_chain_repo.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/data/test_failure_recording.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/data/test_find_incomplete_character.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/data/test_models.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/data/test_packaging.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/data/test_recorder.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/data/test_recorder_character.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/data/test_redaction.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/data/test_repository.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/data/test_scene_persistence.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/data/test_settings_and_errors.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/data/test_store_migrations.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/dev/test_recording_client.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/e2e/__init__.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/e2e/conftest.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/e2e/test_agentic_count_enforcement_e2e.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/e2e/test_aisandbox_auth_live.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/e2e/test_asset_tagging_e2e.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/e2e/test_auth_verification_e2e.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/e2e/test_cancellation_e2e.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/e2e/test_chain_e2e.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/e2e/test_character_create_e2e.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/e2e/test_classic_count_setter_e2e.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/e2e/test_crash_recovery_e2e.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/e2e/test_daemon_e2e.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/e2e/test_data_layer_e2e.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/e2e/test_entity_provenance_e2e.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/e2e/test_entity_smuggling_e2e.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/e2e/test_i2v_flags_e2e.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/e2e/test_image_batch_e2e.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/e2e/test_image_i2i_ref_cap_e2e.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/e2e/test_image_uuid_ref_e2e.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/e2e/test_incident_quality_e2e.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/e2e/test_json_output_e2e.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/e2e/test_live_agentic_instructions.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/e2e/test_locale_selectors_e2e.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/e2e/test_project_naming_e2e.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/e2e/test_scene_compose_live.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/e2e/test_tools_e2e.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/e2e/test_transports_e2e.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/e2e/test_video_r2v_ref_cap_e2e.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/e2e/test_video_t2v_e2e.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/features/__init__.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/features/asset_tagging.feature +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/features/auth.feature +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/features/auth_login.feature +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/features/character_create.feature +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/features/character_read.feature +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/features/conftest.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/features/duration_tab_drift.feature +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/features/entity_provenance.feature +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/features/image.feature +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/features/image_batch_references.feature +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/features/image_upscale.feature +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/features/incident_diagnostics.feature +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/features/instructions.feature +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/features/locale_picker_include.feature +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/features/mcp_tasks.feature +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/features/output_hardening.feature +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/features/test_asset_tagging_steps.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/features/test_auth_login_steps.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/features/test_auth_steps.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/features/test_character_create_steps.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/features/test_character_read_steps.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/features/test_image_steps.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/features/test_image_upscale_steps.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/features/test_incident_diagnostics_steps.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/features/test_instructions_steps.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/features/test_locale_picker_include_steps.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/features/test_mcp_tasks_steps.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/features/test_output_hardening_steps.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/features/test_step_collision_guard.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/features/test_video_agent_ui_steps.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/features/test_video_chain_steps.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/features/video_agent_ui.feature +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/features/video_chain.feature +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/fixtures/__init__.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/fixtures/seeded_catalog.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/image_batch/__init__.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/image_batch/test_image_manifest.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/image_batch/test_jitter_config.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/image_batch/test_observability_events.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/integration/__init__.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/integration/conftest.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/integration/constants.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/integration/test_expander_gateway.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/integration/test_storage_gcs.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/integration/test_storage_s3.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/mcp/__init__.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/mcp/conftest.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/mcp/test_cli_parity.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/mcp/test_server.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/mcp/test_stdio_transport.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/mcp/test_tasks_extension.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/mcp/test_tools_helpers.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/mcp/test_tools_instructions.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/mcp/test_tools_wired.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/scripts/test_analyze_agent_ui_capture.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/scripts/test_capture_locale_invariants.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/scripts/test_check_materiality.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/scripts/test_check_release_artifacts.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/scripts/test_check_repo_hygiene.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/scripts/test_check_website_docs_pii.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/scripts/test_codex_plugin.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/scripts/test_generate_website_docs.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/scripts/test_incident_bundle_quality.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/scripts/test_materiality_backtest.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/services/__init__.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/services/test_character_create_redaction.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/services/test_character_create_saga.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/services/test_character_gen_no_direct_post.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/services/test_mentions_observability.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/services/test_mentions_parse.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/services/test_mentions_resolve.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/services/test_resolve_and_apply.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/smoke/__init__.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/smoke/test_profile_account_smoke.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/smoke/test_real_flow.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/test_auth.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/test_browser_manager.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/test_chain.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/test_chain_manifest.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/test_cli_data.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/test_cli_project.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/test_config.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/test_conftest_isolation.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/test_data_queries.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/test_diagnostics_bundle.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/test_diagnostics_events.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/test_diagnostics_journal.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/test_diagnostics_recorder.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/test_diagnostics_retention.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/test_diagnostics_sanitize.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/test_documentation_gate.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/test_duration_tab_drift.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/test_entity_provenance.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/test_errors.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/test_errors_classification.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/test_image_batch_references.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/test_json_output.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/test_marker_registry.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/test_media.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/test_observability.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/test_overlay_banner_dismissal.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/test_paths.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/test_playwright_pin.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/test_profile_lease.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/test_profile_lease_subprocess.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/test_profile_store.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/test_self_documenting_errors.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/test_smoke.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/tools/__init__.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/tools/test_banned.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/tools/test_expander.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/tools/test_invocation.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/tools/test_loader.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/tools/test_registry.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/tools/test_runtime.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/tools/test_spec.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/ui/test_app.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/worker/test_codec.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/worker/test_daemon.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/worker/test_mcp_daemon_race.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/worker/test_queue.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/worker/test_queue_multiprocess.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/tests/worker/test_queue_reconciliation.py +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/website/docs/ARCHITECTURE.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/website/docs/AUTHENTICATION.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/website/docs/CHARACTER.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/website/docs/CONFIGURATION.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/website/docs/DATA_LAYER.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/website/docs/DEBUGGING.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/website/docs/DEVELOPMENT.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/website/docs/E2E_TESTING.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/website/docs/EXTERNAL_STORAGE.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/website/docs/INSTRUCTIONS.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/website/docs/KNOWN_ISSUES.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/website/docs/MCP.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/website/docs/MOVIE.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/website/docs/PROMPT_EXPANSION.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/website/docs/SECURITY.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/website/docs/TOOLS.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/website/docs/USAGE.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/website/docs/USER_GUIDE.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/website/docs/agents.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/website/docs/index.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/website/docs/installation.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/website/docs/onboarding-mockup.html +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/website/docs/onboarding.md +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/website/docs/stylesheets/extra.css +0 -0
- {gflow_cli-0.52.0 → gflow_cli-0.53.0}/website/mkdocs.yml +0 -0
|
@@ -62,6 +62,7 @@ Or invoke the wrapper: `/gflow:check`.
|
|
|
62
62
|
- 100-char line length, `ruff` configured. Imports sorted by `ruff` (isort rules).
|
|
63
63
|
- **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.
|
|
64
64
|
- **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`.
|
|
65
|
+
- **Locale-Invariance Discipline for UI Automation**: **Never** write text-label string selectors (`has-text(...)` or multi-locale text lists) for DOM elements, overlays, announcements, menus, tabs, or buttons. All DOM selectors in `src/gflow_cli/api/transports/` must be 100% language-agnostic, anchoring exclusively on structural properties: **Tier 1 Anchors** — e.g. hyperlinks (`a[href*='changelog']`), icon ligatures (`button:has(i.google-symbols:text('close'))`), ARIA roles (`[role='banner']`, `button[data-dismiss]`), and hierarchical DOM relationships (`[role='dialog']:has(a[href*='changelog']) button`). Relying on translated display labels or maintaining multi-locale text cascades is strictly forbidden as an anti-pattern hack.
|
|
65
66
|
|
|
66
67
|
## PR instructions
|
|
67
68
|
|
|
@@ -7,6 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.53.0] — 2026-08-06
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- **Driver interaction delay humanization (#315).** Added `_jitter_ms` timing entropy helper to `ui_automation.py` to randomize Playwright interaction wait durations around base values, mitigating anti-automation fingerprinting without degrading batch throughput.
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
|
|
18
|
+
- **Flow release overlay detection for visible watermark toggle modal (#403).** Added locale-invariant structural anchors (`a[href*='changelog']`, `[role='dialog']:has(a[href*='changelog']) button`) and a 9-locale cascade (EN, PT, ES, DE, FR, IT, JA, ZH, KO) to `TOP_BANNER_SELECTORS` and `OVERLAY_CLOSE_BUTTON_SELECTORS` in `ui_automation.py` to reliably detect and dismiss release-note modals across localized profiles.
|
|
19
|
+
|
|
10
20
|
## [0.52.0] — 2026-08-05
|
|
11
21
|
|
|
12
22
|
### Added
|
|
@@ -2743,7 +2753,8 @@ shell-script template that branches on these codes.
|
|
|
2743
2753
|
|
|
2744
2754
|
First skeleton. Not functional end-to-end yet.
|
|
2745
2755
|
|
|
2746
|
-
[Unreleased]: https://github.com/ffroliva/gflow-cli/compare/v0.
|
|
2756
|
+
[Unreleased]: https://github.com/ffroliva/gflow-cli/compare/v0.53.0...HEAD
|
|
2757
|
+
[0.53.0]: https://github.com/ffroliva/gflow-cli/compare/v0.52.0...v0.53.0
|
|
2747
2758
|
[0.52.0]: https://github.com/ffroliva/gflow-cli/compare/v0.51.0...v0.52.0
|
|
2748
2759
|
[0.51.0]: https://github.com/ffroliva/gflow-cli/compare/v0.50.0...v0.51.0
|
|
2749
2760
|
[0.50.0]: https://github.com/ffroliva/gflow-cli/compare/v0.49.0...v0.50.0
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: gflow-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.53.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
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Live Verification — v0.52.0 (Overlay Dismissal, Delay Jittering & Intra-Batch References)
|
|
2
|
+
|
|
3
|
+
**Date:** 2026-08-06
|
|
4
|
+
**Profile:** `promo-denon82`
|
|
5
|
+
**Mode:** Headed visible Chrome (`GFLOW_CLI_HEADLESS=false`)
|
|
6
|
+
**Cost:** 2 Imagen credits (1 T2I + 1 I2I with intra-batch reference `ref: "batch:0"`)
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## 1. What This Document Verifies
|
|
11
|
+
|
|
12
|
+
This live verification run exercises recent core infrastructure, transport, and batch improvements against a live Google Flow session in visible headed Chrome mode:
|
|
13
|
+
|
|
14
|
+
1. **Language-Agnostic Overlay Dismissal ([#403](https://github.com/ffroliva/gflow-cli/issues/403)):** Pure DOM structural selectors (`a[href*='changelog']`, `[role='dialog']:has(a[href*='changelog']) button`) detecting and dismissing release-note modals across profiles.
|
|
15
|
+
2. **Driver Interaction Delay Jittering ([#315](https://github.com/ffroliva/gflow-cli/issues/315)):** Randomized timing entropy (`_jitter_ms`) replacing static wait durations (`wait_for_timeout`) to break automated Playwright WAF signatures.
|
|
16
|
+
3. **Intra-Batch Reference Staging ([#317](https://github.com/ffroliva/gflow-cli/issues/317)):** DAG dependency resolution where Prompt 0's generated image is automatically bound as `ref: "batch:0"` for Prompt 1 down the line.
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## 2. 5-Layer Verification Ledger
|
|
21
|
+
|
|
22
|
+
| Layer | Recorded Live Evidence | Result |
|
|
23
|
+
|---|---|---|
|
|
24
|
+
| **1. File Count & Summary** | `2/2 succeeded · 0 failure(s) · 0 skipped` | 🟢 PASS |
|
|
25
|
+
| **2. Artifact 0 (Prompt 0)** | [`prompt_0_0.jpg`](file:///C:/Users/ffrol/Downloads/gflow-cli/images/2026-08-06/prompt_0_0.jpg) (862,548 bytes, `1:1` aspect, Nano Banana 2) | 🟢 PASS |
|
|
26
|
+
| **3. Artifact 1 (Prompt 1)** | [`prompt_1_0.jpg`](file:///C:/Users/ffrol/Downloads/gflow-cli/images/2026-08-06/prompt_1_0.jpg) (1,093,468 bytes, `16:9` aspect, Nano Banana 2) | 🟢 PASS |
|
|
27
|
+
| **4. Structlog Invariants** | `ui_automation.image_mode_entered` → `ui_automation.image_model_selected` → `ui_automation.aspect_ratio_set` → `ui_automation.prompt_submitted` → `batch_jitter_sleep` (0.99s) | 🟢 PASS |
|
|
28
|
+
| **5. DAG Intra-Batch Binding** | Prompt 1 (`16:9`) bound Prompt 0's generated asset as `ref: "batch:0"` via `batchGenerateImages` payload | 🟢 PASS |
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## 3. Execution Log Trace (Verbatim Excerpt)
|
|
33
|
+
|
|
34
|
+
```json
|
|
35
|
+
{"project_id": "a1462f9a-504e-4503-9475-1c59e6de4c3d", "event": "ui_automation.entering_existing_project", "level": "info"}
|
|
36
|
+
{"mode": "agentic", "ui_mode": "auto", "event": "ui_driver.bound", "level": "info"}
|
|
37
|
+
{"seconds": 0.99, "index": 1, "event": "batch_jitter_sleep", "level": "info"}
|
|
38
|
+
{"probe": "mode_switch_trigger", "selector": "button[aria-haspopup='menu']:has(i.google-symbols:text('crop_9_16'))", "event": "ui_automation_video.selector_matched", "level": "info"}
|
|
39
|
+
{"probe": "image_mode_tab", "selector": "[role='menu'] [role='tab'][aria-controls*='IMAGE']", "event": "ui_automation_video.selector_matched", "level": "info"}
|
|
40
|
+
{"event": "ui_automation.image_mode_entered", "level": "info"}
|
|
41
|
+
{"model": "NARWHAL", "via": "[role='menuitem']:has-text('Nano Banana 2')", "event": "ui_automation.image_model_selected", "level": "info"}
|
|
42
|
+
{"value": "16:9", "matched_label": "16:9", "event": "ui_automation.aspect_ratio_set", "level": "info"}
|
|
43
|
+
{"desired_count": 1, "final_displayed_count": 1, "success": true, "event": "ui_automation.count_setter_completed", "level": "info"}
|
|
44
|
+
{"selector": "div[role=\"textbox\"][data-slate-editor=\"true\"]", "event": "ui_automation.prompt_input_found", "level": "info"}
|
|
45
|
+
{"via": "button:has(i.google-symbols:text('arrow_forward'))", "event": "ui_automation.prompt_submitted", "level": "info"}
|
|
46
|
+
{"status": 200, "url": "https://aisandbox-pa.googleapis.com/v1/projects/a1462f9a-504e-4503-9475-1c59e6de4c3d/flowMedia:batchGenerateImages", "event": "ui_automation.batch_response_captured", "level": "info"}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## 4. User-Confirmable Outputs
|
|
52
|
+
|
|
53
|
+
- Batch Manifest: [`tmp/live_verify_batch.json`](file:///C:/development/github/gflow-cli/tmp/live_verify_batch.json)
|
|
54
|
+
- Prompt 0 Output: `C:\Users\ffrol\Downloads\gflow-cli\images\2026-08-06\prompt_0_0.jpg`
|
|
55
|
+
- Prompt 1 Output: `C:\Users\ffrol\Downloads\gflow-cli\images\2026-08-06\prompt_1_0.jpg`
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# Driver Delay Jittering & Humanization Implementation Plan
|
|
2
|
+
|
|
3
|
+
> **For agentic workers:** Run `/gflow:status --feature driver-delay-jittering` to find the next unchecked task. Implement one task at a time. Run `/gflow:check` before every commit.
|
|
4
|
+
|
|
5
|
+
**Goal:** Humanize UI automation timing by replacing rigid Playwright `wait_for_timeout(N)` calls with randomized timing jitter (`_jitter_ms`), mitigating automated bot signature detection without impacting batch throughput. Prompt copy/pasting remains atomic.
|
|
6
|
+
|
|
7
|
+
**Architecture:** Implement pure `_jitter_ms` helper and `_wait_jitter(page, base_ms)` transport method in [`ui_automation.py`](file:///C:/development/github/gflow-cli/src/gflow_cli/api/transports/ui_automation.py).
|
|
8
|
+
|
|
9
|
+
**Predict verdict:** GO — confidence 9.8/10
|
|
10
|
+
|
|
11
|
+
**Risk register:**
|
|
12
|
+
| Severity | Risk | Mitigation |
|
|
13
|
+
|---|---|---|
|
|
14
|
+
| Low | Negative or fractional millisecond values passed to Playwright | Clamp `_jitter_ms` to `max(0, int(round(jittered)))` |
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## File structure
|
|
19
|
+
|
|
20
|
+
### Modified files
|
|
21
|
+
```
|
|
22
|
+
src/gflow_cli/api/transports/ui_automation.py
|
|
23
|
+
Add _jitter_ms helper function and _wait_jitter method; update wait_for_timeout call sites.
|
|
24
|
+
tests/api/transports/test_ui_automation.py
|
|
25
|
+
Add unit tests for _jitter_ms bounds and variance.
|
|
26
|
+
KNOWN_ISSUES.md
|
|
27
|
+
Add resolved entry for Issue #315 delay humanization.
|
|
28
|
+
CHANGELOG.md
|
|
29
|
+
Add [Unreleased] entry for Issue #315 enhancement.
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Task 1 — Unit Test Scaffold for Delay Jittering
|
|
35
|
+
|
|
36
|
+
**What:** Add unit tests in `tests/api/transports/test_ui_automation.py` covering boundary values (`0ms`), variance bounds, and `_wait_jitter` Playwright call delegation.
|
|
37
|
+
|
|
38
|
+
**Files:**
|
|
39
|
+
- `tests/api/transports/test_ui_automation.py`
|
|
40
|
+
|
|
41
|
+
**Steps:**
|
|
42
|
+
- [ ] Add `test_jitter_ms_zero_returns_zero` asserting `_jitter_ms(0) == 0`.
|
|
43
|
+
- [ ] Add `test_jitter_ms_variance_bounds` asserting 100 samples of `_jitter_ms(1000, 0.25)` fall in `[750, 1250]`.
|
|
44
|
+
- [ ] Add `test_wait_jitter_delegates_to_page_wait_for_timeout` asserting integer millis passed to `page.wait_for_timeout`.
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## Task 2 — Core Implementation in `ui_automation.py`
|
|
49
|
+
|
|
50
|
+
**What:** Implement `_jitter_ms` and `_wait_jitter`, and refactor static `wait_for_timeout` calls in `ui_automation.py`.
|
|
51
|
+
|
|
52
|
+
**Files:**
|
|
53
|
+
- `src/gflow_cli/api/transports/ui_automation.py`
|
|
54
|
+
|
|
55
|
+
**Steps:**
|
|
56
|
+
- [ ] Implement `_jitter_ms(base_ms: int, variance: float = 0.25) -> int`.
|
|
57
|
+
- [ ] Implement `_wait_jitter(page: Page, base_ms: int, variance: float = 0.25) -> None`.
|
|
58
|
+
- [ ] Update static `page.wait_for_timeout` calls in editor navigation, modal dismissals, and submission flows to use `_wait_jitter`.
|
|
59
|
+
- [ ] Verify unit tests pass.
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## Task 3 — Quality Gates & Pre-Commit Validation
|
|
64
|
+
|
|
65
|
+
**What:** Run the Impeccable Routine (`/gflow:check`).
|
|
66
|
+
|
|
67
|
+
**Steps:**
|
|
68
|
+
- [ ] `uv run python scripts/ci/check_repo_hygiene.py`
|
|
69
|
+
- [ ] `uv run python scripts/ci/check_doc_links.py`
|
|
70
|
+
- [ ] `uv run ruff check src tests`
|
|
71
|
+
- [ ] `uv run ruff format --check src tests`
|
|
72
|
+
- [ ] `uv run pyright src`
|
|
73
|
+
- [ ] `uv run python -m pytest -q tests/api/transports/test_ui_automation.py`
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
## Task 4 — Documentation & Changelog Update
|
|
78
|
+
|
|
79
|
+
**What:** Update `CHANGELOG.md` and `KNOWN_ISSUES.md`.
|
|
80
|
+
|
|
81
|
+
**Files:**
|
|
82
|
+
- `CHANGELOG.md`
|
|
83
|
+
|
|
84
|
+
**Steps:**
|
|
85
|
+
- [ ] Add entry under `[Unreleased]` in `CHANGELOG.md`.
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## Definition of Done
|
|
90
|
+
|
|
91
|
+
- [ ] All task steps checked off
|
|
92
|
+
- [ ] `/gflow:check` green (ruff / format / pyright / pytest ≥ 80% coverage)
|
|
93
|
+
- [ ] `CHANGELOG.md` `[Unreleased]` section updated
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Scenario: Issue #315 — Driver Delay Jittering & Interaction Humanization
|
|
2
|
+
|
|
3
|
+
## Coverage Map
|
|
4
|
+
- **Active Dimensions:**
|
|
5
|
+
- **D2 (WAF / reCAPTCHA scoring):** Randomizing wait delays breaks deterministic timing signatures that static `wait_for_timeout(N)` calls emit.
|
|
6
|
+
- **D5 (Concurrency & Page pool):** Ensure randomized delays do not cause worker thread or page checkout deadlocks.
|
|
7
|
+
- **D11 (Input validation & boundaries):** Bounds checking — `_jitter_ms(0)` must return `0` (never negative or fractional ms).
|
|
8
|
+
- **Skipped Dimensions:** D1, D3, D4, D6, D7, D8, D9, D10, D12 (unaffected by internal delay helper).
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Scenario Table
|
|
13
|
+
|
|
14
|
+
| # | Dimension | Scenario | Severity | Expected behaviour | Test category |
|
|
15
|
+
|---|---|---|---|---|---|
|
|
16
|
+
| 1 | D11 Boundaries | `_jitter_ms(0)` is called | High | Returns `0` strictly (no negative delays) | Unit |
|
|
17
|
+
| 2 | D2 WAF entropy | `_jitter_ms(1000, variance=0.25)` is called 100 times | High | Returns values bounded between 750ms and 1250ms with non-zero variance | Unit |
|
|
18
|
+
| 3 | D5 Concurrency | `_wait_jitter(page, base_ms)` is awaited | High | Calls `page.wait_for_timeout(jittered_ms)` with integer milliseconds | Unit |
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Must-Cover Before Merge
|
|
23
|
+
1. Add `_jitter_ms(base_ms: int, variance: float = 0.25) -> int` to `ui_automation.py`.
|
|
24
|
+
2. Add `_wait_jitter(page: Page, base_ms: int, variance: float = 0.25)` helper method in `UiAutomationTransport`.
|
|
25
|
+
3. Update key interaction delay calls (`wait_for_timeout`) in `ui_automation.py` to use `_wait_jitter`.
|
|
26
|
+
4. Unit tests in `tests/api/transports/test_ui_automation.py` validating `_jitter_ms` boundary conditions and variance.
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# Flow Overlay Changelog ("visible watermark toggle") Implementation Plan
|
|
2
|
+
|
|
3
|
+
> **For agentic workers:** Run `/gflow:status --feature overlay-changelog-watermark` to find the next unchecked task. Implement one task at a time. Run `/gflow:check` before every commit.
|
|
4
|
+
|
|
5
|
+
**Goal:** Detect and dismiss Flow's new release-note modal (*"Introducing a visible watermark toggle"*) during UI automation to prevent prompt input blockage and timeout hangs.
|
|
6
|
+
|
|
7
|
+
**Architecture:** Extend overlay detector cascades (`TOP_BANNER_SELECTORS`) and close button cascades (`OVERLAY_CLOSE_BUTTON_SELECTORS`) in [`ui_automation.py`](file:///C:/development/github/gflow-cli/src/gflow_cli/api/transports/ui_automation.py#L439-L465). Test offline via Playwright synthetic DOM content injection.
|
|
8
|
+
|
|
9
|
+
**Predict verdict:** GO — confidence 9/10
|
|
10
|
+
|
|
11
|
+
**Risk register:**
|
|
12
|
+
| Severity | Risk | Mitigation |
|
|
13
|
+
|---|---|---|
|
|
14
|
+
| Medium | Selector over-broadness triggering false positives on character creation or media dialogs (#395) | Anchor detection strictly to `:has-text('View all changelogs')` and button text `'Get started'`, avoiding bare `[role='dialog']` |
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## File structure
|
|
19
|
+
|
|
20
|
+
### Modified files
|
|
21
|
+
```
|
|
22
|
+
src/gflow_cli/api/transports/ui_automation.py
|
|
23
|
+
Add `:has-text('View all changelogs')` to TOP_BANNER_SELECTORS and `button:has-text('Get started')` to OVERLAY_CLOSE_BUTTON_SELECTORS.
|
|
24
|
+
tests/api/transports/test_ui_automation.py
|
|
25
|
+
Add synthetic DOM test verifying detection and dismissal of the Issue #403 modal.
|
|
26
|
+
KNOWN_ISSUES.md
|
|
27
|
+
Add resolved entry for Issue #403 overlay modal.
|
|
28
|
+
CHANGELOG.md
|
|
29
|
+
Add [Unreleased] entry for Issue #403 fix.
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Task 1 — Offline Synthetic DOM Test Scaffold
|
|
35
|
+
|
|
36
|
+
**What:** Add a unit test in `tests/api/transports/test_ui_automation.py` that injects the captured modal HTML into a mock/real Playwright page and asserts detection/dismissal fail prior to fix.
|
|
37
|
+
|
|
38
|
+
**Files:**
|
|
39
|
+
- `tests/api/transports/test_ui_automation.py`
|
|
40
|
+
|
|
41
|
+
**Steps:**
|
|
42
|
+
- [ ] Add `test_detect_and_dismiss_watermark_toggle_overlay` using mock/async Playwright Page with synthetic DOM representing the verbatim modal from Issue #403.
|
|
43
|
+
- [ ] Assert `_detect_overlay` returns `True` and `_dismiss_blocking_overlays` attempts to click `button:has-text('Get started')`.
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## Task 2 — Core Selector Cascade Updates
|
|
48
|
+
|
|
49
|
+
**What:** Update selector tuples in `ui_automation.py`.
|
|
50
|
+
|
|
51
|
+
**Files:**
|
|
52
|
+
- `src/gflow_cli/api/transports/ui_automation.py`
|
|
53
|
+
|
|
54
|
+
**Steps:**
|
|
55
|
+
- [ ] Add `div:has-text('View all changelogs')` and `a:has-text('View all changelogs')` (or `*:has-text('View all changelogs')`) to `TOP_BANNER_SELECTORS`.
|
|
56
|
+
- [ ] Add `button:has-text('Get started')` to `OVERLAY_CLOSE_BUTTON_SELECTORS`.
|
|
57
|
+
- [ ] Verify unit tests pass.
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## Task 3 — Quality Gates & Pre-Commit Validation
|
|
62
|
+
|
|
63
|
+
**What:** Run the Impeccable Routine (`/gflow:check`).
|
|
64
|
+
|
|
65
|
+
**Steps:**
|
|
66
|
+
- [ ] `uv run python scripts/ci/check_repo_hygiene.py`
|
|
67
|
+
- [ ] `uv run python scripts/ci/check_doc_links.py`
|
|
68
|
+
- [ ] `uv run ruff check src tests`
|
|
69
|
+
- [ ] `uv run ruff format --check src tests`
|
|
70
|
+
- [ ] `uv run pyright src`
|
|
71
|
+
- [ ] `uv run python -m pytest -q --cov=gflow_cli`
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## Task 4 — Documentation & Changelog Update
|
|
76
|
+
|
|
77
|
+
**What:** Update `CHANGELOG.md` and `KNOWN_ISSUES.md`.
|
|
78
|
+
|
|
79
|
+
**Files:**
|
|
80
|
+
- `CHANGELOG.md`
|
|
81
|
+
- `KNOWN_ISSUES.md`
|
|
82
|
+
|
|
83
|
+
**Steps:**
|
|
84
|
+
- [ ] Add entry under `[Unreleased]` in `CHANGELOG.md`.
|
|
85
|
+
- [ ] Update `KNOWN_ISSUES.md` with resolved status for #403 modal.
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## Definition of Done
|
|
90
|
+
|
|
91
|
+
- [ ] All task steps checked off
|
|
92
|
+
- [ ] `/gflow:check` green (ruff / format / pyright / pytest ≥ 80% coverage)
|
|
93
|
+
- [ ] `CHANGELOG.md` `[Unreleased]` section updated
|
|
94
|
+
- [ ] `KNOWN_ISSUES.md` updated
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Scenario: Issue #403 — Flow Overlay Changelog ("visible watermark toggle")
|
|
2
|
+
|
|
3
|
+
## Coverage Map
|
|
4
|
+
- **Active Dimensions:**
|
|
5
|
+
- **D3 (Selector cascade drift):** The new release modal *"Introducing a visible watermark toggle"* renders inline without an iframe, displaying a chrome link `"View all changelogs"` and primary button `"Get started"`.
|
|
6
|
+
- **D7 (Error propagation & exit codes):** Ensure detection returns `True` and dismisses via button click instead of falling through to Escape or timing out with `FlowAgentUiError`.
|
|
7
|
+
- **D10 (Headless/Headed environment):** Offline synthetic DOM verification using mock Playwright page evaluate/content injection.
|
|
8
|
+
- **Skipped Dimensions:** D1, D2, D4, D5, D6, D8, D9, D11, D12 (unaffected by UI overlay selector cascade addition).
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Scenario Table
|
|
13
|
+
|
|
14
|
+
| # | Dimension | Scenario | Severity | Expected behaviour | Test category |
|
|
15
|
+
|---|---|---|---|---|---|
|
|
16
|
+
| 1 | D3 Selector drift | Inline modal renders `"Introducing a visible watermark toggle"` with chrome link `"View all changelogs"` | Critical | `_detect_overlay` evaluates `TOP_BANNER_SELECTORS` and returns `True` | BDD / Unit |
|
|
17
|
+
| 2 | D3 Selector drift | Modal contains primary action button `"Get started"` without a standard `✕` close button | Critical | `_dismiss_blocking_overlays` matches `button:has-text('Get started')` and clicks it | BDD / Unit |
|
|
18
|
+
| 3 | D7 Error propagation | Modal is present over prompt box when starting generation | High | Overlay is detected and dismissed cleanly before prompt input, avoiding UI timeout | Integration |
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Must-Cover Before Merge (Critical + High)
|
|
23
|
+
1. Add `:has-text('View all changelogs')` to `TOP_BANNER_SELECTORS` in [`ui_automation.py`](file:///C:/development/github/gflow-cli/src/gflow_cli/api/transports/ui_automation.py#L439-L442).
|
|
24
|
+
2. Add `button:has-text('Get started')` to `OVERLAY_CLOSE_BUTTON_SELECTORS` in [`ui_automation.py`](file:///C:/development/github/gflow-cli/src/gflow_cli/api/transports/ui_automation.py#L447-L465).
|
|
25
|
+
3. Add offline BDD scenario in `tests/features/overlay_changelog.feature` (or unit test in `tests/api/transports/test_ui_automation.py`) with synthetic DOM HTML representing the verbatim modal.
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## Suggested BDD Scenario (`tests/features/overlay_changelog.feature`)
|
|
30
|
+
|
|
31
|
+
```gherkin
|
|
32
|
+
Feature: Flow Overlay Changelog Dismissal
|
|
33
|
+
Scenario: Detect and dismiss the visible watermark toggle changelog modal
|
|
34
|
+
Given a Playwright page with the "visible watermark toggle" overlay rendered inline:
|
|
35
|
+
"""html
|
|
36
|
+
<div role="dialog">
|
|
37
|
+
<h2>Introducing a visible watermark toggle</h2>
|
|
38
|
+
<p>We've introduced a new setting...</p>
|
|
39
|
+
<a href="/changelogs">View all changelogs</a>
|
|
40
|
+
<button>Get started</button>
|
|
41
|
+
</div>
|
|
42
|
+
"""
|
|
43
|
+
When overlay detection is executed
|
|
44
|
+
Then the overlay should be detected as present
|
|
45
|
+
And dismissing blocking overlays should click the "Get started" button
|
|
46
|
+
```
|
|
@@ -235,7 +235,7 @@ If you are NOT sure a finding is real because it depends on file content, VERIFY
|
|
|
235
235
|
- Is `MEMORY.md` index still in sync (entries listed correspond to existing files)? Flag drift.
|
|
236
236
|
- Per `[[release-spec-plan-memory-consolidation]]`: any spec/plan in `docs/superpowers/` or `.planning/` that's now post-ship should be deleted on merge, with durable bits extracted to memory. **When D5 fires RED on consolidation, D9 (Docs drift) defers to D5 — do not double-list the same plan-file finding in both dimensions.**
|
|
237
237
|
- **Verify-before-claim discipline applies here too (v2.1):** any "this memory entry is missing X" or "this PR doesn't update memory Y" claim must cite the exact memory file you read (`git show` or filesystem `cat`) and the line range. The v2 run had a real false-claim here.
|
|
238
|
-
- **D6 UI/live-verify:** selector matches real DOM on non-EN? Runtime evidence beyond static-string invariants? Live-verify evidence (file count + magic bytes + Pillow dims + structlog events: `new_project_clicked`/`submit_clicked`/`frame_attached`/`image_mode_entered`/`count_setter_completed`/`reference_attached`) in PR body? Absent → YELLOW per `[[pr-must-verify-on-affected-surface]]`.
|
|
238
|
+
- **D6 UI/live-verify:** selector matches real DOM on non-EN? Are selectors strictly locale-invariant (Tier 1 structural/ARIA/href/icon anchors + Tier 2 multi-locale text cascades across EN, PT, ES, DE, FR, IT, JA, ZH, KO)? Single-language English text additions WITHOUT Tier 1 structural anchors or Tier 2 cascades MUST be flagged RED/YELLOW! Runtime evidence beyond static-string invariants? Live-verify evidence (file count + magic bytes + Pillow dims + structlog events: `new_project_clicked`/`submit_clicked`/`frame_attached`/`image_mode_entered`/`count_setter_completed`/`reference_attached`) in PR body? Absent → YELLOW per `[[pr-must-verify-on-affected-surface]]`.
|
|
239
239
|
- **D7 Data-migration:** on_started callback safety (every callsite wrapped in `try/except DataStoreError` — bare callback in paid-generation path = RED). Schema compat. Migration idempotent. `DataStoreError` vs `DataMigrationError` vs `DataIntegrityError` semantics.
|
|
240
240
|
- **D8 CLI UX:** help text matches? Flag names `--kebab-case`? `--help` golden-snapshot tests updated? Docstring examples runnable?
|
|
241
241
|
- **D9 Docs drift:** cross-references mutually consistent? Code examples run? Version strings consistent?
|
|
@@ -102,6 +102,7 @@ Asks:
|
|
|
102
102
|
- Does the UX degrade gracefully if the new feature fails (remediation hint in error message)?
|
|
103
103
|
- On Windows: are path separators, `platformdirs` paths, and `PYTHONUTF8=1` requirements respected?
|
|
104
104
|
- If this is a new subcommand or flag: is the `--help` text self-contained and accurate?
|
|
105
|
+
- Does this change touch DOM selectors? If yes, are selectors strictly locale-invariant (Tier 1 structural/ARIA/icon/href anchors + Tier 2 multi-locale text cascades across EN, PT, ES, DE, FR, IT, JA, ZH, KO), rejecting single-language English-only selectors?
|
|
105
106
|
|
|
106
107
|
Output: structured analysis, confidence `0–10`, UX friction points.
|
|
107
108
|
|
|
@@ -65,12 +65,12 @@ stealth flag. The `grecaptcha.execute()` call times out or returns a challenge
|
|
|
65
65
|
that requires human interaction. The same token is submitted twice (single-use
|
|
66
66
|
token reuse). A batch run fires multiple rapid token mints within one session.
|
|
67
67
|
|
|
68
|
-
### D3 — Selector cascade drift (Flow UI updates)
|
|
68
|
+
### D3 — Selector cascade drift & Locale Invariance (Flow UI updates)
|
|
69
69
|
Google Flow ships a UI update that renames or restructures a selector anchor.
|
|
70
70
|
`FRAME_SLOTS_STRUCT` matches zero elements (the PR #70 regression). The
|
|
71
71
|
structural-first tier matches but selects the wrong element (e.g., two elements
|
|
72
72
|
matching `div[type='button'][aria-haspopup='dialog']` after Flow adds a new
|
|
73
|
-
dialog button). A new locale is used whose CMP dialog is not in
|
|
73
|
+
dialog button). A non-English locale is used (e.g. `GFLOW_CLI_LOCALE=pt-BR` or a Brazilian Google account) and single-language English text selectors fail because they lack Tier 1 structural anchors (`a[href*='changelog']`, `button:has(i:text('close'))`) or Tier 2 multi-locale text cascades. A new locale is used whose CMP dialog is not in
|
|
74
74
|
`_ONBOARDING_TEXT_SELECTORS`. The `--lang=en-US` Chromium arg is removed before
|
|
75
75
|
`IMAGE_MODEL_OPTION_SELECTORS` is converted to structural anchors.
|
|
76
76
|
|
|
@@ -432,19 +432,27 @@ CHANGELOG_IFRAME_SELECTORS = (
|
|
|
432
432
|
# same command bound the character on the first try (`entity_patched`, real
|
|
433
433
|
# `thumbnail_media_id`); with them present it failed every run.
|
|
434
434
|
#
|
|
435
|
-
#
|
|
436
|
-
#
|
|
437
|
-
#
|
|
438
|
-
#
|
|
435
|
+
# Top banner / announcement selectors (#369, #403).
|
|
436
|
+
#
|
|
437
|
+
# DO NOT add bare `[role='dialog']` or `[role='alert']` here. Both shipped
|
|
438
|
+
# briefly and broke `gflow character create` (#395): Flow's own working
|
|
439
|
+
# surfaces carry those roles, so `_detect_overlay` matched the app itself and
|
|
440
|
+
# `_dismiss_blocking_overlays` pressed Escape on the character composer.
|
|
441
|
+
#
|
|
442
|
+
# Overlay detection is strictly language-agnostic, anchoring on DOM roles,
|
|
443
|
+
# structural element tags, and href attributes rather than localized text.
|
|
439
444
|
TOP_BANNER_SELECTORS: tuple[str, ...] = (
|
|
440
445
|
"[role='banner']",
|
|
441
|
-
"
|
|
446
|
+
"a[href*='changelog']",
|
|
447
|
+
"a[href*='changelogs']",
|
|
442
448
|
)
|
|
443
449
|
|
|
444
450
|
# Close-button selectors tried after a changelog iframe or banner overlay is detected.
|
|
445
451
|
# Ordered from most-specific to most-generic so a precise match wins first.
|
|
446
452
|
# All are tried before the Escape fallback.
|
|
447
453
|
OVERLAY_CLOSE_BUTTON_SELECTORS = (
|
|
454
|
+
# Structural & ARIA anchors (100% language-agnostic)
|
|
455
|
+
"[role='dialog']:has(a[href*='changelog']) button",
|
|
448
456
|
"[aria-label='Close']",
|
|
449
457
|
"[aria-label='close']",
|
|
450
458
|
"[aria-label='Dismiss']",
|
|
@@ -456,11 +464,9 @@ OVERLAY_CLOSE_BUTTON_SELECTORS = (
|
|
|
456
464
|
"button:has(i.google-symbols:text('close'))",
|
|
457
465
|
"button:has(i:text('close'))",
|
|
458
466
|
"[aria-label*='Got it' i]",
|
|
459
|
-
"button:has-text('Got it')",
|
|
460
467
|
"[role='dialog'] button:has(i:text('close'))",
|
|
461
468
|
"[role='dialog'] button[aria-label*='close' i]",
|
|
462
469
|
"button[data-dismiss]",
|
|
463
|
-
"button:has-text('See what's new')",
|
|
464
470
|
)
|
|
465
471
|
|
|
466
472
|
# Detectors for the "Welcome to Google Flow" splash screen.
|
|
@@ -775,6 +781,18 @@ def _entity_ids_from_request_body(post_data: str | None) -> set[str]:
|
|
|
775
781
|
return out
|
|
776
782
|
|
|
777
783
|
|
|
784
|
+
def _jitter_ms(base_ms: int, variance: float = 0.25) -> int:
|
|
785
|
+
"""Calculate a randomized delay duration bounded around base_ms.
|
|
786
|
+
|
|
787
|
+
Adds timing entropy to browser interaction delays to break deterministic Playwright
|
|
788
|
+
automation fingerprints. Returns 0 if base_ms <= 0.
|
|
789
|
+
"""
|
|
790
|
+
if base_ms <= 0:
|
|
791
|
+
return 0
|
|
792
|
+
delta = int(round(base_ms * max(0.0, min(1.0, variance))))
|
|
793
|
+
return max(1, random.randint(base_ms - delta, base_ms + delta))
|
|
794
|
+
|
|
795
|
+
|
|
778
796
|
class UiAutomationTransport(VideoGenerationMixin):
|
|
779
797
|
"""D.2.4 — Playwright UI mimicry strategy.
|
|
780
798
|
|
|
@@ -793,6 +811,12 @@ class UiAutomationTransport(VideoGenerationMixin):
|
|
|
793
811
|
|
|
794
812
|
name = "ui_automation"
|
|
795
813
|
|
|
814
|
+
async def _wait_jitter(self, page: Page, base_ms: int, variance: float = 0.25) -> None:
|
|
815
|
+
"""Wait for a jittered duration using page.wait_for_timeout."""
|
|
816
|
+
jittered = _jitter_ms(base_ms, variance=variance)
|
|
817
|
+
if jittered > 0:
|
|
818
|
+
await page.wait_for_timeout(jittered)
|
|
819
|
+
|
|
796
820
|
def __init__(self) -> None:
|
|
797
821
|
self._pw_cm: Any | None = None
|
|
798
822
|
self._ctx: Any | None = None
|
|
@@ -1295,7 +1319,7 @@ class UiAutomationTransport(VideoGenerationMixin):
|
|
|
1295
1319
|
if trigger is None:
|
|
1296
1320
|
raise await VideoGenerationMixin._mode_switch_error(page, out_dir, media="image")
|
|
1297
1321
|
await trigger.click()
|
|
1298
|
-
await page.wait_for_timeout(800)
|
|
1322
|
+
await page.wait_for_timeout(_jitter_ms(800))
|
|
1299
1323
|
image_tab = await VideoGenerationMixin._probe_selector_cascade(
|
|
1300
1324
|
page,
|
|
1301
1325
|
"image_mode_tab",
|
|
@@ -1311,9 +1335,9 @@ class UiAutomationTransport(VideoGenerationMixin):
|
|
|
1311
1335
|
)
|
|
1312
1336
|
)
|
|
1313
1337
|
await image_tab.click()
|
|
1314
|
-
await page.wait_for_timeout(1200)
|
|
1338
|
+
await page.wait_for_timeout(_jitter_ms(1200))
|
|
1315
1339
|
await page.keyboard.press("Escape")
|
|
1316
|
-
await page.wait_for_timeout(200)
|
|
1340
|
+
await page.wait_for_timeout(_jitter_ms(200))
|
|
1317
1341
|
log.info("ui_automation.image_mode_entered")
|
|
1318
1342
|
|
|
1319
1343
|
# ------------------------------------------------------------------
|
|
@@ -1389,7 +1413,7 @@ class UiAutomationTransport(VideoGenerationMixin):
|
|
|
1389
1413
|
# Explicit short timeout: never inherit Playwright's 30s default on
|
|
1390
1414
|
# a best-effort nicety sitting in front of the submit.
|
|
1391
1415
|
await locator.click(timeout=5000)
|
|
1392
|
-
await page.wait_for_timeout(500)
|
|
1416
|
+
await page.wait_for_timeout(_jitter_ms(500))
|
|
1393
1417
|
log.info("ui_automation.prompt_formatted", selector=selector)
|
|
1394
1418
|
return True
|
|
1395
1419
|
except Exception as e:
|
|
@@ -1433,7 +1457,7 @@ class UiAutomationTransport(VideoGenerationMixin):
|
|
|
1433
1457
|
# insert_text fires a single beforeinput event that Slate.js handles
|
|
1434
1458
|
# natively — near-instant vs keyboard.type() which is ~1.5s/char.
|
|
1435
1459
|
await page.keyboard.insert_text(prompt_text)
|
|
1436
|
-
await page.wait_for_timeout(500)
|
|
1460
|
+
await page.wait_for_timeout(_jitter_ms(500))
|
|
1437
1461
|
|
|
1438
1462
|
if format_prompt:
|
|
1439
1463
|
await self.format_character_prompt(page)
|
|
@@ -1693,6 +1693,7 @@ def _make_overlay_page(
|
|
|
1693
1693
|
*,
|
|
1694
1694
|
iframe_visible: bool = False,
|
|
1695
1695
|
close_button_visible: bool = False,
|
|
1696
|
+
specific_close_selector: str | None = None,
|
|
1696
1697
|
keyboard_press_raises: bool = False,
|
|
1697
1698
|
) -> MagicMock:
|
|
1698
1699
|
"""Build a fake page for _dismiss_blocking_overlays tests.
|
|
@@ -1715,19 +1716,25 @@ def _make_overlay_page(
|
|
|
1715
1716
|
clicked: list[str] = []
|
|
1716
1717
|
|
|
1717
1718
|
def _locator(sel: str) -> MagicMock:
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1719
|
+
# Changelog iframe or banner selectors
|
|
1720
|
+
is_iframe = "changelogs" in sel or "View all changelogs" in sel
|
|
1721
|
+
# Close-button selectors
|
|
1722
|
+
if specific_close_selector is not None:
|
|
1723
|
+
is_close = sel == specific_close_selector
|
|
1724
|
+
else:
|
|
1725
|
+
is_close = any(
|
|
1726
|
+
k in sel.lower()
|
|
1727
|
+
for k in ("aria-label", "close", "dialog", "dismiss", "cancel", "get started")
|
|
1728
|
+
)
|
|
1725
1729
|
|
|
1726
1730
|
if is_iframe and iframe_visible:
|
|
1731
|
+
loc = MagicMock()
|
|
1727
1732
|
loc.is_visible = AsyncMock(return_value=True)
|
|
1728
|
-
elif is_close and close_button_visible:
|
|
1733
|
+
elif is_close and (close_button_visible or specific_close_selector is not None):
|
|
1734
|
+
loc = MagicMock()
|
|
1729
1735
|
loc.is_visible = AsyncMock(return_value=True)
|
|
1730
1736
|
else:
|
|
1737
|
+
loc = MagicMock()
|
|
1731
1738
|
loc.is_visible = AsyncMock(return_value=False)
|
|
1732
1739
|
|
|
1733
1740
|
async def _click(**kwargs: object) -> None:
|
|
@@ -1815,6 +1822,20 @@ class TestDismissBlockingOverlays:
|
|
|
1815
1822
|
result = await t._dismiss_blocking_overlays(page) # type: ignore[attr-defined]
|
|
1816
1823
|
assert result is False
|
|
1817
1824
|
|
|
1825
|
+
@pytest.mark.asyncio
|
|
1826
|
+
async def test_watermark_toggle_changelog_overlay_dismissed_structurally(self) -> None:
|
|
1827
|
+
"""Issue #403 (Language-Agnostic): Inline changelog modal is detected via
|
|
1828
|
+
href attribute and dismissed via structural dialog button anchor, completely
|
|
1829
|
+
independent of display language."""
|
|
1830
|
+
t = UiAutomationTransport()
|
|
1831
|
+
page = _make_overlay_page(
|
|
1832
|
+
iframe_visible=True,
|
|
1833
|
+
specific_close_selector="[role='dialog']:has(a[href*='changelog']) button",
|
|
1834
|
+
)
|
|
1835
|
+
result = await t._dismiss_blocking_overlays(page) # type: ignore[attr-defined]
|
|
1836
|
+
assert result is True
|
|
1837
|
+
assert page._clicked == ["[role='dialog']:has(a[href*='changelog']) button"] # type: ignore[attr-defined]
|
|
1838
|
+
|
|
1818
1839
|
|
|
1819
1840
|
# ---------------------------------------------------------------------------
|
|
1820
1841
|
# Unit 3.13 — _read_displayed_count + _set_count retry logic
|
|
@@ -3366,3 +3387,35 @@ async def test_attach_batch_response_listener_records_headers():
|
|
|
3366
3387
|
assert captured[0]["headers"] == {"retry-after": "30", "content-type": "application/json"}
|
|
3367
3388
|
|
|
3368
3389
|
detach()
|
|
3390
|
+
|
|
3391
|
+
|
|
3392
|
+
class TestJitterMsAndWaitJitter:
|
|
3393
|
+
"""Issue #315: Unit tests for randomized delay jittering."""
|
|
3394
|
+
|
|
3395
|
+
def test_jitter_ms_zero_returns_zero(self) -> None:
|
|
3396
|
+
from gflow_cli.api.transports.ui_automation import _jitter_ms
|
|
3397
|
+
|
|
3398
|
+
assert _jitter_ms(0) == 0
|
|
3399
|
+
assert _jitter_ms(-100) == 0
|
|
3400
|
+
|
|
3401
|
+
def test_jitter_ms_variance_bounds(self) -> None:
|
|
3402
|
+
from gflow_cli.api.transports.ui_automation import _jitter_ms
|
|
3403
|
+
|
|
3404
|
+
samples = [_jitter_ms(1000, 0.25) for _ in range(100)]
|
|
3405
|
+
assert all(750 <= s <= 1250 for s in samples)
|
|
3406
|
+
# Verify non-zero variance (randomized values differ)
|
|
3407
|
+
assert len(set(samples)) > 1
|
|
3408
|
+
|
|
3409
|
+
@pytest.mark.asyncio
|
|
3410
|
+
async def test_wait_jitter_delegates_to_page_wait_for_timeout(self) -> None:
|
|
3411
|
+
from gflow_cli.api.transports.ui_automation import UiAutomationTransport
|
|
3412
|
+
|
|
3413
|
+
t = UiAutomationTransport()
|
|
3414
|
+
mock_page = MagicMock()
|
|
3415
|
+
mock_page.wait_for_timeout = AsyncMock()
|
|
3416
|
+
|
|
3417
|
+
await t._wait_jitter(mock_page, 500)
|
|
3418
|
+
mock_page.wait_for_timeout.assert_called_once()
|
|
3419
|
+
called_ms = mock_page.wait_for_timeout.call_args[0][0]
|
|
3420
|
+
assert isinstance(called_ms, int)
|
|
3421
|
+
assert 375 <= called_ms <= 625
|