gflow-cli 0.6.0a6__tar.gz → 0.7.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.
Files changed (232) hide show
  1. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/.claude/README.md +8 -3
  2. gflow_cli-0.7.0/.claude/commands/gflow/changelog.md +21 -0
  3. gflow_cli-0.7.0/.claude/commands/gflow/check.md +48 -0
  4. gflow_cli-0.7.0/.claude/commands/gflow/known-issues.md +20 -0
  5. gflow_cli-0.7.0/.claude/commands/gflow/plan.md +39 -0
  6. gflow_cli-0.7.0/.claude/commands/gflow/release.md +118 -0
  7. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/.github/CODEOWNERS +1 -0
  8. gflow_cli-0.7.0/.github/PULL_REQUEST_TEMPLATE.md +20 -0
  9. gflow_cli-0.7.0/.github/copilot-instructions.md +24 -0
  10. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/.github/workflows/ci.yml +16 -8
  11. gflow_cli-0.7.0/.github/workflows/external-pr-triage.yml +126 -0
  12. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/.github/workflows/release.yml +18 -3
  13. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/CHANGELOG.md +54 -1
  14. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/CLAUDE.md +22 -18
  15. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/CONTRIBUTING.md +33 -5
  16. gflow_cli-0.7.0/KNOWN_ISSUES.md +326 -0
  17. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/PKG-INFO +24 -44
  18. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/PLAN.md +40 -0
  19. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/README.md +23 -43
  20. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/RELEASE.md +2 -2
  21. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/docs/ARCHITECTURE.md +1 -0
  22. gflow_cli-0.7.0/docs/DEBUGGING.md +183 -0
  23. gflow_cli-0.7.0/docs/DEVELOPMENT.md +125 -0
  24. gflow_cli-0.7.0/docs/GITHUB.md +139 -0
  25. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/docs/INDEX.md +29 -0
  26. gflow_cli-0.7.0/docs/LIVE_VERIFICATION_v0.7.0.md +110 -0
  27. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/docs/USAGE.md +64 -10
  28. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/docs/USER_GUIDE.md +87 -0
  29. gflow_cli-0.7.0/docs/superpowers/2026-05-17-issue-15-handover.md +59 -0
  30. gflow_cli-0.7.0/docs/superpowers/plans/2026-05-17-e2e-test-coverage.md +463 -0
  31. gflow_cli-0.7.0/docs/superpowers/plans/2026-05-17-issue-15-auth-verification-fix.md +1449 -0
  32. gflow_cli-0.7.0/docs/superpowers/plans/2026-05-17-issue-15-i2v-bearer-auth.md +811 -0
  33. gflow_cli-0.7.0/docs/superpowers/plans/2026-05-17-issue-15-orchestration.md +118 -0
  34. gflow_cli-0.7.0/docs/superpowers/plans/2026-05-18-video-phase0-submit-spike.md +697 -0
  35. gflow_cli-0.7.0/docs/superpowers/plans/2026-05-19-video-phase-a-execution-state.md +64 -0
  36. gflow_cli-0.7.0/docs/superpowers/plans/2026-05-19-video-phase-a-orchestration.md +164 -0
  37. gflow_cli-0.7.0/docs/superpowers/plans/2026-05-19-video-phase-a-t2v.md +2083 -0
  38. gflow_cli-0.7.0/docs/superpowers/specs/2026-05-17-e2e-test-coverage-design.md +190 -0
  39. gflow_cli-0.7.0/docs/superpowers/specs/2026-05-17-i2v-uploadimage-401-bearer-auth-design.md +330 -0
  40. gflow_cli-0.7.0/docs/superpowers/specs/2026-05-17-issue-15-auth-verification-fix-design.md +485 -0
  41. gflow_cli-0.7.0/docs/superpowers/specs/2026-05-17-issue-15-root-cause-findings.md +87 -0
  42. gflow_cli-0.7.0/docs/superpowers/specs/2026-05-18-ui-automation-video-generation-design.md +739 -0
  43. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/pyproject.toml +1 -1
  44. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/samples/captured/02_batchAsyncGenerateVideoText.json +3 -3
  45. gflow_cli-0.7.0/samples/captured/08_batchAsyncGenerateVideoStartAndEndImage.json +144 -0
  46. gflow_cli-0.7.0/samples/captured/09_batchAsyncGenerateVideoReferenceImages.json +136 -0
  47. gflow_cli-0.7.0/samples/captured/10_batchCheckAsyncVideoGenerationStatus_successful.json +90 -0
  48. gflow_cli-0.7.0/samples/captured/11_batchCheckAsyncVideoGenerationStatus_failed.json +97 -0
  49. gflow_cli-0.7.0/scripts/dev/active_plan.py +188 -0
  50. gflow_cli-0.7.0/scripts/smoke_video_editor.py +874 -0
  51. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/src/gflow_cli/__init__.py +1 -1
  52. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/src/gflow_cli/api/__init__.py +1 -3
  53. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/src/gflow_cli/api/client.py +151 -111
  54. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/src/gflow_cli/api/dto.py +0 -67
  55. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/src/gflow_cli/api/recaptcha.py +1 -1
  56. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/src/gflow_cli/api/transports/base.py +2 -2
  57. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/src/gflow_cli/api/transports/experimental/bearer.py +3 -1
  58. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/src/gflow_cli/api/transports/experimental/evaluate_fetch.py +7 -1
  59. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/src/gflow_cli/api/transports/experimental/sapisidhash.py +3 -1
  60. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/src/gflow_cli/api/transports/ui_automation.py +200 -19
  61. gflow_cli-0.7.0/src/gflow_cli/api/transports/ui_automation_video.py +498 -0
  62. gflow_cli-0.7.0/src/gflow_cli/api/video.py +156 -0
  63. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/src/gflow_cli/auth/internal_chromium.py +56 -23
  64. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/src/gflow_cli/auth/real_chrome.py +61 -34
  65. gflow_cli-0.7.0/src/gflow_cli/auth/verification.py +228 -0
  66. gflow_cli-0.7.0/src/gflow_cli/cli_video.py +95 -0
  67. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/src/gflow_cli/errors.py +58 -4
  68. gflow_cli-0.7.0/src/gflow_cli/exceptions.py +25 -0
  69. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/tasks/lessons.md +34 -0
  70. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/tests/api/test_client.py +86 -2
  71. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/tests/api/test_client_image.py +116 -65
  72. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/tests/api/test_dto.py +1 -38
  73. gflow_cli-0.7.0/tests/api/test_video.py +213 -0
  74. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/tests/api/transports/test_ui_automation.py +242 -4
  75. gflow_cli-0.7.0/tests/api/transports/test_ui_automation_video.py +392 -0
  76. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/tests/auth/strategies/test_strategies.py +127 -50
  77. gflow_cli-0.7.0/tests/auth/test_verification.py +301 -0
  78. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/tests/cli/test_error_handling.py +17 -1
  79. gflow_cli-0.7.0/tests/e2e/conftest.py +67 -0
  80. gflow_cli-0.7.0/tests/e2e/test_auth_verification_e2e.py +65 -0
  81. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/tests/e2e/test_transports_e2e.py +72 -0
  82. gflow_cli-0.7.0/tests/e2e/test_video_t2v_e2e.py +139 -0
  83. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/tests/features/conftest.py +0 -2
  84. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/tests/features/test_step_collision_guard.py +2 -4
  85. gflow_cli-0.7.0/tests/test_cli_video.py +44 -0
  86. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/tests/test_errors.py +28 -0
  87. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/uv.lock +1 -1
  88. gflow_cli-0.6.0a6/.claude/commands/release.md +0 -97
  89. gflow_cli-0.6.0a6/KNOWN_ISSUES.md +0 -198
  90. gflow_cli-0.6.0a6/scripts/smoke_e2e.py +0 -78
  91. gflow_cli-0.6.0a6/src/gflow_cli/api/video.py +0 -112
  92. gflow_cli-0.6.0a6/src/gflow_cli/cli_video.py +0 -341
  93. gflow_cli-0.6.0a6/tests/api/test_client_generate_video.py +0 -93
  94. gflow_cli-0.6.0a6/tests/api/test_video.py +0 -83
  95. gflow_cli-0.6.0a6/tests/features/test_video_steps.py +0 -253
  96. gflow_cli-0.6.0a6/tests/features/video.feature +0 -27
  97. gflow_cli-0.6.0a6/tests/test_cli_video.py +0 -220
  98. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/.env.template +0 -0
  99. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/.gitattributes +0 -0
  100. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/.github/dependabot.yml +0 -0
  101. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/.gitignore +0 -0
  102. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/.gitleaks.toml +0 -0
  103. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/.planning/todos/pending/2026-05-11-add-project-logo-and-docs-site-promotion-plan.md +0 -0
  104. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/.pre-commit-config.yaml +0 -0
  105. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/.secrets.baseline +0 -0
  106. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/CONFIGURATION.md +0 -0
  107. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/DISCLAIMER.md +0 -0
  108. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/LICENSE +0 -0
  109. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/docs/AUTHENTICATION.md +0 -0
  110. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/docs/CONFIGURATION.md +0 -0
  111. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/docs/SECURITY.md +0 -0
  112. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/docs/assets/example-run.gif +0 -0
  113. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/docs/superpowers/plans/2026-05-09-image-mvp-orchestration.md +0 -0
  114. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/docs/superpowers/plans/2026-05-09-image-mvp.md +0 -0
  115. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/docs/superpowers/plans/2026-05-09-video-mvp-orchestration.md +0 -0
  116. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/docs/superpowers/plans/2026-05-09-video-mvp.md +0 -0
  117. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/docs/superpowers/plans/2026-05-10-phase-4-hardening-orchestration.md +0 -0
  118. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/docs/superpowers/plans/2026-05-10-phase-4-hardening.md +0 -0
  119. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/docs/superpowers/plans/2026-05-14-shell-multi-prompt/2026-05-14-shell-multi-prompt-orchestration.md +0 -0
  120. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/docs/superpowers/plans/2026-05-14-shell-multi-prompt/COUNCIL_FINAL_ARCH.md +0 -0
  121. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/docs/superpowers/plans/2026-05-14-shell-multi-prompt/COUNCIL_FINAL_SEC_UX.md +0 -0
  122. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/docs/superpowers/plans/2026-05-14-shell-multi-prompt/COUNCIL_REVIEW_CODE.md +0 -0
  123. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/docs/superpowers/plans/2026-05-14-shell-multi-prompt/COUNCIL_REVIEW_GEMINI.md +0 -0
  124. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/docs/superpowers/plans/2026-05-14-shell-multi-prompt/COUNCIL_REVIEW_SECURITY.md +0 -0
  125. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/docs/superpowers/plans/2026-05-14-shell-multi-prompt/IMPLEMENTATION_REVIEW_PYTHON.md +0 -0
  126. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/docs/superpowers/plans/2026-05-14-shell-multi-prompt/IMPLEMENTATION_REVIEW_SECURITY.md +0 -0
  127. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/docs/superpowers/plans/2026-05-14-shell-multi-prompt/PLAN.md +0 -0
  128. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/docs/superpowers/plans/2026-05-14-shell-multi-prompt/PLAN_REVIEW_CODE.md +0 -0
  129. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/docs/superpowers/plans/2026-05-14-shell-multi-prompt/PLAN_REVIEW_FOLLOWUP.md +0 -0
  130. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/docs/superpowers/plans/2026-05-14-shell-multi-prompt/PLAN_REVIEW_PLANNER.md +0 -0
  131. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/docs/superpowers/plans/2026-05-14-shell-multi-prompt/PLAN_REVIEW_SECURITY.md +0 -0
  132. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/docs/superpowers/plans/2026-05-14-shell-multi-prompt/PLAN_REVIEW_SECURITY_FOLLOWUP.md +0 -0
  133. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/docs/superpowers/plans/2026-05-15-auth-login-real-chrome/COUNCIL_FINAL_SEC_UX_VERIFIED.md +0 -0
  134. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/docs/superpowers/plans/2026-05-15-auth-login-real-chrome/COUNCIL_REVIEW_PLAN_SECURITY.md +0 -0
  135. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/docs/superpowers/plans/2026-05-15-auth-login-real-chrome/COUNCIL_REVIEW_SPEC_SECURITY.md +0 -0
  136. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/docs/superpowers/plans/2026-05-15-auth-login-real-chrome/PLAN.md +0 -0
  137. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/docs/superpowers/plans/2026-05-15-auth-login-real-chrome/orchestration.md +0 -0
  138. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/docs/superpowers/specs/2026-05-10-phase-4-hardening-design.md +0 -0
  139. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/docs/superpowers/specs/2026-05-14-shell-multi-prompt-design.md +0 -0
  140. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/docs/superpowers/specs/2026-05-15-auth-login-real-chrome-design.md +0 -0
  141. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/docs/superpowers/verifications/2026-05-11-phase-4-stage-g.md +0 -0
  142. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/examples/README.md +0 -0
  143. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/examples/batch_from_config.py +0 -0
  144. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/examples/multi_prompt_t2i.py +0 -0
  145. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/examples/sample_config.json +0 -0
  146. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/examples/sample_prompts.txt +0 -0
  147. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/examples/single_image_t2i.py +0 -0
  148. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/samples/README.md +0 -0
  149. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/samples/captured/01_upload_image.json +0 -0
  150. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/samples/captured/03_batchCheckAsyncVideoGenerationStatus.json +0 -0
  151. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/samples/captured/04_archive_workflow.json +0 -0
  152. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/samples/captured/05_createProject.json +0 -0
  153. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/samples/captured/06_batchGenerateImages.json +0 -0
  154. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/samples/captured/07_batchGenerateImages_seeded.json +0 -0
  155. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/scripts/ci/check_repo_hygiene.py +0 -0
  156. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/scripts/debug_editor.py +0 -0
  157. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/scripts/debug_gen_settings.py +0 -0
  158. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/scripts/debug_settings.py +0 -0
  159. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/scripts/diag_capture_flow_traffic.py +0 -0
  160. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/scripts/diag_recaptcha_mint.py +0 -0
  161. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/scripts/record_demo.ps1 +0 -0
  162. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/scripts/smoke_image.py +0 -0
  163. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/scripts/smoke_real_chrome_image.py +0 -0
  164. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/scripts/smoke_worker_style.py +0 -0
  165. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/scripts/verify_chrome_auth_viability.py +0 -0
  166. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/skills/README.md +0 -0
  167. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/skills/gflow-cli/SKILL.md +0 -0
  168. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/sonar-project.properties +0 -0
  169. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/src/gflow_cli/__main__.py +0 -0
  170. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/src/gflow_cli/_cli_helpers.py +0 -0
  171. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/src/gflow_cli/api/_retry.py +0 -0
  172. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/src/gflow_cli/api/image.py +0 -0
  173. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/src/gflow_cli/api/routes.py +0 -0
  174. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/src/gflow_cli/api/transports/__init__.py +0 -0
  175. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/src/gflow_cli/api/transports/_common.py +0 -0
  176. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/src/gflow_cli/api/transports/_fingerprint.py +0 -0
  177. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/src/gflow_cli/api/transports/experimental/__init__.py +0 -0
  178. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/src/gflow_cli/auth/__init__.py +0 -0
  179. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/src/gflow_cli/auth/base.py +0 -0
  180. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/src/gflow_cli/auth/factory.py +0 -0
  181. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/src/gflow_cli/auth/strategies.py +0 -0
  182. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/src/gflow_cli/browser_manager.py +0 -0
  183. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/src/gflow_cli/cli.py +0 -0
  184. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/src/gflow_cli/cli_image.py +0 -0
  185. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/src/gflow_cli/cli_run.py +0 -0
  186. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/src/gflow_cli/config.py +0 -0
  187. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/src/gflow_cli/image_batch.py +0 -0
  188. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/src/gflow_cli/manifest.py +0 -0
  189. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/src/gflow_cli/observability.py +0 -0
  190. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/src/gflow_cli/paths.py +0 -0
  191. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/src/gflow_cli/profile_store.py +0 -0
  192. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/tests/__init__.py +0 -0
  193. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/tests/api/__init__.py +0 -0
  194. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/tests/api/test_concurrency.py +0 -0
  195. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/tests/api/test_image.py +0 -0
  196. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/tests/api/test_image_dto.py +0 -0
  197. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/tests/api/test_recaptcha.py +0 -0
  198. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/tests/api/test_retry.py +0 -0
  199. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/tests/api/test_routes.py +0 -0
  200. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/tests/api/transports/__init__.py +0 -0
  201. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/tests/api/transports/test_base.py +0 -0
  202. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/tests/api/transports/test_bearer.py +0 -0
  203. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/tests/api/transports/test_common.py +0 -0
  204. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/tests/api/transports/test_evaluate_fetch.py +0 -0
  205. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/tests/api/transports/test_factory.py +0 -0
  206. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/tests/api/transports/test_fingerprint.py +0 -0
  207. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/tests/api/transports/test_sapisidhash.py +0 -0
  208. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/tests/auth/strategies/test_factory.py +0 -0
  209. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/tests/cli/__init__.py +0 -0
  210. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/tests/cli/test_cli_image.py +0 -0
  211. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/tests/cli/test_cli_run.py +0 -0
  212. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/tests/cli/test_helpers.py +0 -0
  213. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/tests/cli/test_t2i_multi_prompt.py +0 -0
  214. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/tests/conftest.py +0 -0
  215. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/tests/e2e/__init__.py +0 -0
  216. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/tests/features/__init__.py +0 -0
  217. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/tests/features/auth.feature +0 -0
  218. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/tests/features/auth_login.feature +0 -0
  219. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/tests/features/image.feature +0 -0
  220. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/tests/features/test_auth_login_steps.py +0 -0
  221. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/tests/features/test_auth_steps.py +0 -0
  222. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/tests/features/test_image_steps.py +0 -0
  223. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/tests/smoke/__init__.py +0 -0
  224. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/tests/smoke/test_real_flow.py +0 -0
  225. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/tests/test_auth.py +0 -0
  226. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/tests/test_browser_manager.py +0 -0
  227. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/tests/test_config.py +0 -0
  228. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/tests/test_manifest.py +0 -0
  229. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/tests/test_observability.py +0 -0
  230. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/tests/test_paths.py +0 -0
  231. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/tests/test_profile_store.py +0 -0
  232. {gflow_cli-0.6.0a6 → gflow_cli-0.7.0}/tests/test_smoke.py +0 -0
@@ -10,7 +10,12 @@ This directory holds **internal maintainer workflows** that are bundled with the
10
10
  .claude/
11
11
  ├── README.md ← this file
12
12
  └── commands/ ← repo-local slash commands
13
- └── release.md ← `/release` automates the version-bump + tag + push flow
13
+ └── gflow/ ← `/gflow:*` namespace (avoids collision with built-ins)
14
+ ├── check.md ← `/gflow:check` — hygiene + ruff + pyright + pytest
15
+ ├── plan.md ← `/gflow:plan` — show active phase / superpowers plan
16
+ ├── known-issues.md← `/gflow:known-issues` — open/mitigated items
17
+ ├── changelog.md ← `/gflow:changelog` — [Unreleased] + last tagged
18
+ └── release.md ← `/gflow:release` — full release flow (signed tags)
14
19
  ```
15
20
 
16
21
  Optional additions when needed:
@@ -25,9 +30,9 @@ Optional additions when needed:
25
30
 
26
31
  ## Adding a slash command
27
32
 
28
- Drop a Markdown file into `commands/`. Filename (without `.md`) becomes the command name. The first paragraph is the description Claude shows in `/help`. The rest is the prompt the agent executes.
33
+ Drop a Markdown file into `commands/gflow/` to add a `/gflow:<name>` command. Filename (without `.md`) becomes the command name. The first paragraph is the description Claude shows in `/help`. The rest is the prompt the agent executes. **Use the `gflow/` subdirectory** so commands stay namespaced and don't collide with Claude Code built-ins or user-global commands.
29
34
 
30
- Example: `commands/foo.md` → invoked as `/foo`.
35
+ Example: `commands/gflow/foo.md` → invoked as `/gflow:foo`.
31
36
 
32
37
  ## Adding an internal skill
33
38
 
@@ -0,0 +1,21 @@
1
+ ---
2
+ description: Show unreleased changes and last tagged version — insight into recent work.
3
+ ---
4
+
5
+ # `/gflow:changelog` — Recent changes
6
+
7
+ Read CHANGELOG.md and surface what's queued and what recently shipped.
8
+
9
+ ## Steps
10
+
11
+ 1. Read [CHANGELOG.md](../../../CHANGELOG.md)
12
+ 2. Return:
13
+ - All entries under `## [Unreleased]` (empty = nothing queued yet)
14
+ - The most recent versioned section (last tagged release) for comparison
15
+ 3. One-line summary: "X features, Y fixes queued since vZ."
16
+
17
+ ## When to call
18
+
19
+ - Before cutting a release (called automatically by `/gflow:release` as its first step)
20
+ - When you need a quick picture of recent work without opening the file
21
+ - When writing a commit message and unsure if a change is user-visible enough to log
@@ -0,0 +1,48 @@
1
+ ---
2
+ description: Auto-fix lint and formatting, then report types and tests. Run before every commit.
3
+ ---
4
+
5
+ # `/gflow:check` — Quality gates
6
+
7
+ Run in order. Stop and report if a step fails after the fix pass.
8
+
9
+ ## Steps
10
+
11
+ **1. Repo hygiene** (read-only — checks tmp/ output rule, secret files, etc.)
12
+
13
+ ```bash
14
+ PYTHONUTF8=1 uv run python scripts/ci/check_repo_hygiene.py
15
+ ```
16
+
17
+ **2. Auto-fix lint and formatting** (rewrites files in place)
18
+
19
+ ```bash
20
+ uv run ruff check --fix src tests
21
+ uv run ruff format src tests
22
+ ```
23
+
24
+ Report which files were modified. Do NOT stage or commit — leave the diff for review.
25
+
26
+ **3. Type check** (report only — cannot auto-fix)
27
+
28
+ ```bash
29
+ uv run pyright src
30
+ ```
31
+
32
+ **4. Tests + coverage** (report only)
33
+
34
+ ```bash
35
+ uv run pytest -q --cov=gflow_cli --cov-fail-under=80
36
+ ```
37
+
38
+ ## Output
39
+
40
+ - List files changed by the fix pass (empty = nothing needed fixing)
41
+ - All pyright errors with `file:line` references
42
+ - Pytest summary line and coverage percentage
43
+ - Final verdict: all gates pass / which gates failed
44
+
45
+ ## Notes
46
+
47
+ Ruff fix and format may rewrite multiple files. Always `git diff` before staging.
48
+ Pyright errors and test failures require manual intervention — do not attempt silent workarounds.
@@ -0,0 +1,20 @@
1
+ ---
2
+ description: Surface open known issues. Call before touching auth, reCAPTCHA, or anything previously flagged.
3
+ ---
4
+
5
+ # `/gflow:known-issues` — Open issues
6
+
7
+ Read KNOWN_ISSUES.md and return items that are still open or mitigated (not resolved).
8
+
9
+ ## Steps
10
+
11
+ 1. Read [KNOWN_ISSUES.md](../../../KNOWN_ISSUES.md)
12
+ 2. Return only items with status **open** or **mitigated**
13
+ 3. Flag any that are relevant to the current task context
14
+
15
+ ## When to call
16
+
17
+ - Before touching `src/gflow_cli/auth.py`
18
+ - Before touching `src/gflow_cli/api/recaptcha.py`
19
+ - Before any work the user flags as "this felt flaky before"
20
+ - When a test or behaviour feels unexpectedly broken
@@ -0,0 +1,39 @@
1
+ ---
2
+ description: Show the active plan — next task if a superpowers plan is running, current phase otherwise.
3
+ ---
4
+
5
+ # `/gflow:plan` — Active plan
6
+
7
+ ## Steps
8
+
9
+ **1. Check conversation context.**
10
+
11
+ Has the user mentioned a specific feature or invoked the write-plan skill in this session?
12
+ If yes, note the feature name (e.g. `shell-multi-prompt`, `image-mvp`, `phase-4-hardening`).
13
+
14
+ **2. Run the discovery script.**
15
+
16
+ With a feature name identified in step 1:
17
+ ```bash
18
+ uv run python scripts/dev/active_plan.py --feature <feature-name>
19
+ ```
20
+
21
+ Without a feature name (uses most-recent superpowers plan, falls back to PLAN.md):
22
+ ```bash
23
+ uv run python scripts/dev/active_plan.py
24
+ ```
25
+
26
+ **3. Return the output verbatim.**
27
+
28
+ The script already filters to the relevant block. Do not read additional files.
29
+
30
+ ## What the script returns
31
+
32
+ - **Superpowers plan active:** file path, title, goal, progress (X/N steps), and the next unchecked task block
33
+ - **No superpowers plan:** the first incomplete phase from `PLAN.md` (scope, sequence, definition of done)
34
+
35
+ ## When to call
36
+
37
+ - When starting a task and unsure what's in scope
38
+ - When the user asks "what are we working on?" or "what's next?"
39
+ - Before adding a feature, to check it belongs to the current scope
@@ -0,0 +1,118 @@
1
+ ---
2
+ description: Cut a new gflow-cli release — bump version, update CHANGELOG, tag, push.
3
+ ---
4
+
5
+ # `/gflow:release` — Cut a new release
6
+
7
+ Follow this sequence verbatim. Every step matters.
8
+
9
+ ## Inputs
10
+
11
+ Ask the user (if not already provided):
12
+ 1. **Version** — the new version (e.g. `0.4.0`, `0.4.0a3`, `1.0.0rc1`). Use PEP 440 prerelease suffixes (`aN`, `bN`, `rcN`). If they don't know, run `/gflow:changelog` first and propose the next bump (PATCH for fixes only, MINOR for new features, MAJOR for breaks).
13
+ 2. **Pre-release?** — prerelease versions should stay marked as GitHub prereleases. Only the user can say when a release line is ready for the stable tag.
14
+
15
+ ## Sequence
16
+
17
+ **1. Review what's queued.**
18
+
19
+ Run `/gflow:changelog` — confirm the `[Unreleased]` block is non-empty and accurate before proceeding.
20
+
21
+ **2. Verify clean working tree.**
22
+
23
+ ```bash
24
+ git status --short
25
+ ```
26
+
27
+ Must be empty. If not, abort and tell the user to commit or stash first.
28
+
29
+ **3. Verify on `main`, up-to-date with `origin/main`.**
30
+
31
+ ```bash
32
+ git rev-parse --abbrev-ref HEAD # must be "main"
33
+ git fetch origin
34
+ git rev-list HEAD..origin/main # must be empty
35
+ ```
36
+
37
+ **4. Run quality gates.**
38
+
39
+ Run `/gflow:check` — all gates must pass. Abort if any fail.
40
+
41
+ **5. Bump version** in `pyproject.toml`:
42
+
43
+ ```toml
44
+ [project]
45
+ version = "<NEW_VERSION>"
46
+ ```
47
+
48
+ **6. Bump package version** in `src/gflow_cli/__init__.py`:
49
+
50
+ ```python
51
+ __version__ = "<NEW_VERSION>"
52
+ ```
53
+
54
+ **7. Update version assertion tests** if present:
55
+
56
+ ```bash
57
+ rg -n "__version__|<OLD_VERSION>|version assertion" tests src pyproject.toml
58
+ ```
59
+
60
+ **8. Migrate CHANGELOG.**
61
+
62
+ - Move all entries under `## [Unreleased]` to a new `## [<NEW_VERSION>] — YYYY-MM-DD` section.
63
+ - Leave `## [Unreleased]` empty.
64
+ - Update the link footer:
65
+ ```
66
+ [Unreleased]: https://github.com/ffroliva/gflow-cli/compare/v<NEW_VERSION>...HEAD
67
+ [<NEW_VERSION>]: https://github.com/ffroliva/gflow-cli/releases/tag/v<NEW_VERSION>
68
+ ```
69
+
70
+ **9. Review commands for staleness.**
71
+
72
+ Scan `.claude/commands/gflow/` — check if any command references a phase, file path, or behaviour that the release changes. Update in the same commit if so.
73
+
74
+ **10. Commit the release prep.**
75
+
76
+ ```bash
77
+ git add pyproject.toml src/gflow_cli/__init__.py CHANGELOG.md tests
78
+ git commit -m "chore(release): v<NEW_VERSION>"
79
+ ```
80
+
81
+ **11. Tag.** Use `-s` for a signed annotated tag so GitHub shows the **"Verified"** badge AND `.github/workflows/release.yml` passes the signed-tag gate (lightweight or unsigned tags are rejected).
82
+
83
+ ```bash
84
+ git tag -s v<NEW_VERSION> -m "v<NEW_VERSION>"
85
+ ```
86
+
87
+ Requires a GPG or SSH signing key registered in your GitHub account settings.
88
+ Run `git config --global user.signingkey` to confirm a key is set.
89
+ If signing is not available in the current environment, create the tag on
90
+ your local machine and push it: `git push origin v<NEW_VERSION>`.
91
+
92
+ **12. Push commit + tag.**
93
+
94
+ ```bash
95
+ git push origin main
96
+ git push origin v<NEW_VERSION>
97
+ ```
98
+
99
+ **13. Report.**
100
+
101
+ Tell the user:
102
+ - The pushed tag triggers `.github/workflows/release.yml`.
103
+ - Watch <https://github.com/ffroliva/gflow-cli/actions> for the release workflow.
104
+ - On success: PyPI publish + GitHub Release with auto-generated notes.
105
+ - On failure (most common: PyPI Trusted Publishing not yet configured): point to <https://pypi.org/manage/account/publishing/>.
106
+
107
+ ## Critical reminders
108
+
109
+ - **NEVER** add `Co-Authored-By: Claude` (or any AI co-author) to the release commit.
110
+ - **NEVER** force-push a release tag once it's on GitHub. Ship a PATCH fix instead.
111
+ - **NEVER** `--no-verify` past hooks. Fix the underlying issue.
112
+ - If quality gates fail at step 4, **STOP**. Surface the failures to the user.
113
+
114
+ ## See also
115
+
116
+ - [RELEASE.md](../../../RELEASE.md) — full release protocol, prerelease policy, and checklist
117
+ - [README § Releases](../../../README.md#releases) — release policy and cadence
118
+ - [PLAN § Phase 5](../../../PLAN.md#phase-5--public-alpha-release-on-pypi) — first-release exit criteria
@@ -20,3 +20,4 @@
20
20
 
21
21
  # Auth handling — sensitive, never bypass review
22
22
  /src/gflow_cli/auth.py @ffroliva
23
+ /src/gflow_cli/auth/ @ffroliva
@@ -0,0 +1,20 @@
1
+ ## Summary
2
+
3
+ <!-- What changed and why? Link issues with "Fixes #123" when applicable. -->
4
+
5
+ ## Validation
6
+
7
+ <!-- List the focused commands you ran, plus any checks you could not run. -->
8
+
9
+ - [ ] Focused tests added or updated for behavior changes
10
+ - [ ] `uv run ruff check src tests`
11
+ - [ ] `uv run pyright src`
12
+ - [ ] Relevant pytest command:
13
+
14
+ ## Contribution Checklist
15
+
16
+ - [ ] This PR targets `develop`, unless it is a release or emergency fix
17
+ - [ ] My commits use my real Git identity or GitHub noreply email
18
+ - [ ] External contribution commits include `Signed-off-by:` (`git commit -s`)
19
+ - [ ] I did not include secrets, cookies, account tokens, signed URLs, or private captured data
20
+ - [ ] I reviewed any AI-assisted changes before submitting
@@ -0,0 +1,24 @@
1
+ # Copilot Code Review Instructions
2
+
3
+ Review this repository as a Python CLI that automates browser-authenticated
4
+ Google Flow workflows. Treat auth, browser automation, CI, release, and secret
5
+ handling changes as high-risk even when the diff is small.
6
+
7
+ For pull request reviews:
8
+
9
+ - Check that PRs target `develop`, unless they are release PRs.
10
+ - Flag unclear contributor provenance, missing DCO sign-off, placeholder author
11
+ emails, and any copied private data.
12
+ - Look for leaked tokens, cookies, signed URLs, local profile paths, and captured
13
+ Google/Flow request data.
14
+ - For auth/browser changes, check that the implementation preserves profile
15
+ isolation, does not weaken local path boundaries, and avoids remote debugging
16
+ unless explicitly documented.
17
+ - For CI changes, check forked-PR secret behavior and avoid recommending
18
+ `pull_request_target` for jobs that checkout or execute contributor code.
19
+ - For behavior changes, expect focused tests and docs/changelog updates.
20
+ - Keep findings concrete: reference files/lines, explain the user-visible risk,
21
+ and separate blocking issues from cosmetic suggestions.
22
+
23
+ Do not approve pull requests. Copilot review is advisory; maintainer approval is
24
+ still required.
@@ -2,7 +2,7 @@ name: CI
2
2
 
3
3
  on:
4
4
  push:
5
- branches: [main]
5
+ branches: [develop, main]
6
6
  pull_request:
7
7
 
8
8
  env:
@@ -14,7 +14,7 @@ jobs:
14
14
  name: Secret scan (gitleaks)
15
15
  runs-on: ubuntu-latest
16
16
  steps:
17
- - uses: actions/checkout@v4
17
+ - uses: actions/checkout@v6
18
18
  with:
19
19
  fetch-depth: 0 # full history so gitleaks can diff against base
20
20
 
@@ -30,10 +30,10 @@ jobs:
30
30
  matrix:
31
31
  python-version: ["3.11", "3.12", "3.13"]
32
32
  steps:
33
- - uses: actions/checkout@v4
33
+ - uses: actions/checkout@v6
34
34
 
35
35
  - name: Install uv
36
- uses: astral-sh/setup-uv@v3
36
+ uses: astral-sh/setup-uv@v7
37
37
 
38
38
  - name: Set up Python
39
39
  run: uv python install ${{ matrix.python-version }}
@@ -66,7 +66,7 @@ jobs:
66
66
  # Upload coverage XML so the sonar job can consume it
67
67
  - name: Upload coverage report
68
68
  if: matrix.python-version == '3.11'
69
- uses: actions/upload-artifact@v4
69
+ uses: actions/upload-artifact@v7
70
70
  with:
71
71
  name: coverage-xml
72
72
  path: coverage.xml
@@ -77,14 +77,22 @@ jobs:
77
77
  name: SonarCloud analysis
78
78
  runs-on: ubuntu-latest
79
79
  needs: test # wait for tests + coverage report
80
- if: always() # run even if test matrix has failures Sonar should see the state
80
+ # Forked pull_request runs do not receive repository secrets, so SONAR_TOKEN
81
+ # is empty there and the scanner fails before analysis. Keep SonarCloud on
82
+ # trusted pushes/internal PRs where the token is available.
83
+ if: >
84
+ always() &&
85
+ (
86
+ github.event_name != 'pull_request' ||
87
+ github.event.pull_request.head.repo.full_name == github.repository
88
+ )
81
89
  steps:
82
- - uses: actions/checkout@v4
90
+ - uses: actions/checkout@v6
83
91
  with:
84
92
  fetch-depth: 0 # shallow clones break blame / new-code detection
85
93
 
86
94
  - name: Download coverage report
87
- uses: actions/download-artifact@v4
95
+ uses: actions/download-artifact@v8
88
96
  with:
89
97
  name: coverage-xml
90
98
  continue-on-error: true # graceful if coverage upload was skipped
@@ -0,0 +1,126 @@
1
+ name: External PR Triage
2
+
3
+ on:
4
+ pull_request_target:
5
+ types: [opened, reopened, synchronize, ready_for_review, edited]
6
+
7
+ permissions:
8
+ contents: read
9
+ issues: write
10
+ pull-requests: write
11
+
12
+ jobs:
13
+ triage:
14
+ name: Label and route external PRs
15
+ runs-on: ubuntu-latest
16
+ steps:
17
+ - name: Triage external pull request
18
+ uses: actions/github-script@v7
19
+ with:
20
+ script: |
21
+ const pr = context.payload.pull_request;
22
+ if (!pr) {
23
+ core.info("No pull request payload; nothing to do.");
24
+ return;
25
+ }
26
+
27
+ const owner = context.repo.owner;
28
+ const repo = context.repo.repo;
29
+ const issue_number = pr.number;
30
+ const isBot = pr.user?.type === "Bot";
31
+ const trustedAssociations = new Set(["OWNER", "MEMBER", "COLLABORATOR"]);
32
+ const isFork = pr.head.repo.full_name !== pr.base.repo.full_name;
33
+ const isExternal = isFork || !trustedAssociations.has(pr.author_association);
34
+
35
+ if (isBot) {
36
+ core.info("Bot PR; skipping human external-contribution triage.");
37
+ return;
38
+ }
39
+
40
+ if (!isExternal) {
41
+ core.info("PR is not external; skipping external triage.");
42
+ return;
43
+ }
44
+
45
+ const labels = [
46
+ {
47
+ name: "external-contribution",
48
+ color: "0e8a16",
49
+ description: "Pull request from a non-maintainer or fork",
50
+ },
51
+ {
52
+ name: "needs-maintainer-review",
53
+ color: "fbca04",
54
+ description: "Requires maintainer review before merge",
55
+ },
56
+ {
57
+ name: "needs-copilot-review",
58
+ color: "5319e7",
59
+ description: "Ask GitHub Copilot for advisory code review",
60
+ },
61
+ ];
62
+
63
+ for (const label of labels) {
64
+ try {
65
+ await github.rest.issues.createLabel({ owner, repo, ...label });
66
+ } catch (error) {
67
+ if (error.status !== 422) {
68
+ throw error;
69
+ }
70
+ }
71
+ }
72
+
73
+ await github.rest.issues.addLabels({
74
+ owner,
75
+ repo,
76
+ issue_number,
77
+ labels: labels.map((label) => label.name),
78
+ });
79
+
80
+ try {
81
+ await github.rest.pulls.requestReviewers({
82
+ owner,
83
+ repo,
84
+ pull_number: issue_number,
85
+ reviewers: ["ffroliva"],
86
+ });
87
+ } catch (error) {
88
+ core.warning(`Could not request maintainer review: ${error.message}`);
89
+ }
90
+
91
+ const marker = "<!-- gflow-cli-external-pr-triage -->";
92
+ const body = `${marker}
93
+ Thanks for the contribution. This PR has been marked as an external contribution and routed for maintainer review.
94
+
95
+ Before merge, please make sure:
96
+
97
+ - The PR targets \`develop\`.
98
+ - Commits use a real Git identity or GitHub noreply email.
99
+ - External commits include a DCO sign-off: \`git commit -s\`.
100
+ - The PR does not include secrets, cookies, account tokens, signed URLs, or private captured data.
101
+ - Focused tests/docs are included for behavior changes.
102
+
103
+ GitHub Copilot code review may be requested as an advisory first pass, but maintainer approval is still required.`;
104
+
105
+ const comments = await github.paginate(github.rest.issues.listComments, {
106
+ owner,
107
+ repo,
108
+ issue_number,
109
+ per_page: 100,
110
+ });
111
+ const existing = comments.find((comment) => comment.body?.includes(marker));
112
+ if (existing) {
113
+ await github.rest.issues.updateComment({
114
+ owner,
115
+ repo,
116
+ comment_id: existing.id,
117
+ body,
118
+ });
119
+ } else {
120
+ await github.rest.issues.createComment({
121
+ owner,
122
+ repo,
123
+ issue_number,
124
+ body,
125
+ });
126
+ }
@@ -18,16 +18,31 @@ jobs:
18
18
  env:
19
19
  FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
20
20
  steps:
21
- - uses: actions/checkout@v4
21
+ - uses: actions/checkout@v6
22
22
  with:
23
23
  fetch-depth: 0
24
24
 
25
25
  - name: Install uv
26
- uses: astral-sh/setup-uv@v3
26
+ uses: astral-sh/setup-uv@v7
27
27
 
28
28
  - name: Set up Python
29
29
  run: uv python install 3.12
30
30
 
31
+ - name: Verify tag is signed
32
+ run: |
33
+ TAG=${GITHUB_REF_NAME}
34
+ # Lightweight tags resolve directly to a commit, not a tag object.
35
+ TYPE=$(git cat-file -t "$TAG")
36
+ if [ "$TYPE" != "tag" ]; then
37
+ echo "::error::$TAG is a lightweight tag. Use 'git tag -s' to create a signed annotated tag."
38
+ exit 1
39
+ fi
40
+ # Annotated but unsigned tags have no signature header in the object.
41
+ if ! git cat-file -p "$TAG" | grep -qE "BEGIN (PGP|SSH) SIGNATURE"; then
42
+ echo "::error::$TAG is not signed. Use 'git tag -s' when cutting releases."
43
+ exit 1
44
+ fi
45
+
31
46
  - name: Verify tag matches pyproject version
32
47
  run: |
33
48
  TAG=${GITHUB_REF_NAME#v}
@@ -46,7 +61,7 @@ jobs:
46
61
  # Configure once at https://pypi.org/manage/account/publishing/
47
62
 
48
63
  - name: Create GitHub Release
49
- uses: softprops/action-gh-release@v2
64
+ uses: softprops/action-gh-release@v3
50
65
  with:
51
66
  generate_release_notes: true
52
67
  files: dist/*
@@ -7,6 +7,58 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.7.0] — 2026-05-20
11
+
12
+ > **Downstream-worker ergonomics release.** Hardens `FlowApiClient` for
13
+ > long-lived integrations: standard exception module name, optional
14
+ > `project_id`, `health_check()` for liveness probes, `out_dir` for
15
+ > debug-screenshot plumbing, and a stable library-owned error when the
16
+ > underlying browser session dies. Plus auth-flow fixes from issues #15 and
17
+ > #17 and overlay-dismiss for first-run profiles (#26).
18
+
19
+ ### Added
20
+
21
+ - `gflow_cli.exceptions` module as a standard alias for `gflow_cli.errors` — both module names resolve identically. Closes [#16](https://github.com/ffroliva/gflow-cli/issues/16).
22
+ - `FlowApiClient.health_check()` async method — returns `True` if browser context is alive and on a Google domain; safe to call from long-lived workers without try/except. Closes [#16](https://github.com/ffroliva/gflow-cli/issues/16).
23
+ - `FlowApiClient(out_dir=...)` constructor argument — when set, the resolved transport stores it as `_out_dir` so internal `_capture_debug_screenshot` calls inside `UiAutomationTransport._generate_images_locked` (entering the editor, dismissing overlays, sending prompts) save artifacts to that directory. Long-lived workers can now diagnose selector failures without restructuring their call sites. Closes [#18](https://github.com/ffroliva/gflow-cli/issues/18).
24
+ - `BrowserSessionClosedError` (`gflow_cli.errors`, exit code 15) — raised from `FlowApiClient.generate_image()` / `generate_images_batch()` when the underlying Playwright page/context is closed mid-call (Playwright `TargetClosedError`). Callers can now catch a stable library-owned class and recreate the client via `async with FlowApiClient(...)` instead of importing from `playwright._impl._errors`. Closes [#18](https://github.com/ffroliva/gflow-cli/issues/18).
25
+ - `UiAutomationTransport._dismiss_blocking_overlays(page)` — generic overlay-dismiss helper that detects Flow changelog ("What's new") iframes and dismisses them via a close-button selector cascade with an Escape-key fallback. Invoked after editor entry on both image and video flows so first-run profiles no longer fail on the next click. Closes [#26](https://github.com/ffroliva/gflow-cli/issues/26).
26
+ - Release tags must now be **signed annotated tags** (`git tag -s vX.Y.Z`). CI's release job rejects unsigned tags so the GitHub release surfaces as Verified ([#30](https://github.com/ffroliva/gflow-cli/issues/30)).
27
+ - New documentation: [`docs/DEBUGGING.md`](docs/DEBUGGING.md) — evergreen reference for debugging, testing, and troubleshooting (listener log keys, selector-cascade discipline, lifecycle errors, Windows console encoding, test-suite memory). [`docs/LIVE_VERIFICATION_v0.7.0.md`](docs/LIVE_VERIFICATION_v0.7.0.md) — per-release end-to-end evidence (every CLI aspect ratio live-tested).
28
+
29
+ ### Changed
30
+
31
+ - `FlowApiClient.generate_image()` and `generate_images_batch()`: `project_id` is now optional (`str | None = None`). When omitted, a new Flow project is created automatically. Existing callers passing an explicit `project_id` are unaffected. Closes [#16](https://github.com/ffroliva/gflow-cli/issues/16).
32
+ - `gflow video t2v/i2v/batch` now report "temporarily unavailable" — video generation is being rebuilt on the UI-automation transport (Phase A ships the T2V transport; CLI commands return in Phase B).
33
+
34
+ ### Removed
35
+
36
+ - The 401-dead HTTP video API path (`FlowApiClient.generate_video`, `get_video_status`) — retired in favour of the new UI-automation transport (`VideoGenerationMixin` in `api/transports/ui_automation_video.py`).
37
+
38
+ ### Fixed
39
+
40
+ - `gflow auth login` now verifies a real Flow app session before reporting
41
+ success — fixes issue [#15](https://github.com/ffroliva/gflow-cli/issues/15), where a Google-only sign-in was wrongly accepted
42
+ and later failed with HTTP 401.
43
+ - **`gflow auth login --browser internal` now fails fast when Google rejects
44
+ Playwright's bundled Chromium**, returning `AuthBrowserRejectedError` exit
45
+ code 14 with guidance to rerun using real Chrome
46
+ (`gflow auth login --browser chrome`) or set
47
+ `GFLOW_CLI_AUTH_BROWSER=chrome` ([#17](https://github.com/ffroliva/gflow-cli/issues/17)).
48
+ - **`gflow image t2i --aspect 1:1` aspect-ratio tab regression** — Flow's
49
+ `1:1` tab is now selected via an exact-match (`:text-is`) cascade against
50
+ the labels `1:1`, `Square`, `1×1`, `1x1` instead of the prior
51
+ `:has-text("1:1")` substring match. The substring selector was matching an
52
+ invisible parent on some Flow UI variants, causing a 3 s timeout and a
53
+ silent fallback to Flow's default aspect. All five CLI aspect ratios
54
+ (`16:9`, `9:16`, `1:1`, `4:3`, `3:4`) are now live-verified.
55
+ - `UiAutomationTransport._attach_batch_response_listener` now emits a
56
+ `ui_automation.batch_response_seen` log for every `batchGenerateImages`
57
+ URL observed (BEFORE the per-project filter) and a
58
+ `ui_automation.batch_response_dropped_project_id_mismatch` log when the
59
+ filter rejects a response. Eliminates the silent black-hole that hid
60
+ listener-miss bugs during live verification.
61
+
10
62
  ## [0.6.0a6] — 2026-05-17
11
63
 
12
64
  > **Stability & code-quality release.** Fixes a concurrency bug in image
@@ -633,7 +685,8 @@ shell-script template that branches on these codes.
633
685
 
634
686
  First skeleton. Not functional end-to-end yet.
635
687
 
636
- [Unreleased]: https://github.com/ffroliva/gflow-cli/compare/v0.6.0a6...HEAD
688
+ [Unreleased]: https://github.com/ffroliva/gflow-cli/compare/v0.7.0...HEAD
689
+ [0.7.0]: https://github.com/ffroliva/gflow-cli/compare/v0.6.0a6...v0.7.0
637
690
  [0.6.0a6]: https://github.com/ffroliva/gflow-cli/compare/v0.6.0a5...v0.6.0a6
638
691
  [0.6.0a5]: https://github.com/ffroliva/gflow-cli/compare/v0.6.0a4...v0.6.0a5
639
692
  [0.6.0a1]: https://github.com/ffroliva/gflow-cli/compare/v0.5.0a1...v0.6.0a1