gflow-cli 0.10.0__tar.gz → 0.12.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 (426) hide show
  1. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/.claude/README.md +4 -1
  2. gflow_cli-0.12.0/.claude/commands/gflow/active.md +13 -0
  3. gflow_cli-0.12.0/.claude/commands/gflow/next.md +12 -0
  4. gflow_cli-0.12.0/.claude/commands/gflow/plan.md +22 -0
  5. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/.claude/commands/gflow/predict.md +7 -1
  6. gflow_cli-0.12.0/.claude/commands/gflow/release.md +241 -0
  7. gflow_cli-0.12.0/.claude/commands/gflow/status.md +12 -0
  8. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/.gitignore +6 -0
  9. gflow_cli-0.12.0/.planning/issue-125-fix.md +207 -0
  10. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/AGENTS.md +22 -4
  11. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/CHANGELOG.md +150 -1
  12. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/CLAUDE.md +17 -2
  13. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/GEMINI.md +3 -2
  14. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/KNOWN_ISSUES.md +116 -10
  15. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/PKG-INFO +12 -2
  16. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/PLAN.md +2 -2
  17. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/README.md +7 -1
  18. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docs/AGENT_GUIDE.md +12 -1
  19. gflow_cli-0.12.0/docs/CHARACTER.md +506 -0
  20. gflow_cli-0.12.0/docs/CHARACTER_RECON.md +147 -0
  21. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docs/CONFIGURATION.md +35 -0
  22. gflow_cli-0.12.0/docs/DEMOS.md +47 -0
  23. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docs/INDEX.md +17 -3
  24. gflow_cli-0.12.0/docs/LIVE_VERIFICATION_v0.11.0.md +100 -0
  25. gflow_cli-0.12.0/docs/LIVE_VERIFICATION_v0.12.0.md +83 -0
  26. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docs/PROJECT_STATUS.md +9 -2
  27. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docs/USAGE.md +248 -0
  28. gflow_cli-0.12.0/docs/assets/demo-split-pf.gif +0 -0
  29. gflow_cli-0.12.0/docs/superpowers/character-scenario.md +140 -0
  30. gflow_cli-0.12.0/docs/superpowers/plans/2026-05-30-l0-sapisidhash-aisandbox-auth.md +697 -0
  31. gflow_cli-0.12.0/docs/superpowers/plans/2026-05-31-l0-bearer-pivot.md +97 -0
  32. gflow_cli-0.12.0/docs/superpowers/plans/2026-05-31-l1-scene-compose.md +1480 -0
  33. gflow_cli-0.12.0/docs/superpowers/plans/2026-05-31-scene-concat-extend.md +100 -0
  34. gflow_cli-0.12.0/docs/superpowers/plans/2026-06-02-character-creation-phase2.md +293 -0
  35. gflow_cli-0.12.0/docs/superpowers/plans/2026-06-02-character-creation.md +300 -0
  36. gflow_cli-0.12.0/docs/superpowers/specs/2026-05-30-add-clip-scene-timeline-design.md +195 -0
  37. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/examples/README.md +4 -0
  38. gflow_cli-0.12.0/examples/workflow_chain.py +314 -0
  39. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/llms.txt +2 -1
  40. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/pyproject.toml +14 -1
  41. gflow_cli-0.12.0/samples/captured/12_create_scene.json +6 -0
  42. gflow_cli-0.12.0/samples/captured/13_sceneWorkflows_update.json +6 -0
  43. gflow_cli-0.12.0/samples/captured/14_get_scene_workflows.json +6 -0
  44. gflow_cli-0.12.0/samples/captured/15_commit_flowWorkflow.json +6 -0
  45. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/scripts/ci/check_doc_links.py +1 -0
  46. gflow_cli-0.12.0/scripts/dev/_spike_common.py +111 -0
  47. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/scripts/dev/active_plan.py +1 -1
  48. gflow_cli-0.12.0/scripts/dev/capture_i2v_intercept_submit.py +262 -0
  49. gflow_cli-0.12.0/scripts/dev/capture_i2v_model_select_repro.py +104 -0
  50. gflow_cli-0.12.0/scripts/dev/capture_i2v_post_bind_state.py +288 -0
  51. gflow_cli-0.12.0/scripts/dev/character_create_spike.py +344 -0
  52. gflow_cli-0.12.0/scripts/dev/character_create_spike_v2.py +499 -0
  53. gflow_cli-0.12.0/scripts/dev/dump_character_selectors.js +74 -0
  54. gflow_cli-0.12.0/scripts/dev/skillopt/README.md +106 -0
  55. gflow_cli-0.12.0/scripts/dev/skillopt/harness.py +365 -0
  56. gflow_cli-0.12.0/scripts/dev/skillopt/tasks.json +242 -0
  57. gflow_cli-0.12.0/scripts/dev/spike_char_editor_dom.py +237 -0
  58. gflow_cli-0.12.0/scripts/dev/spike_char_gen_capture.py +349 -0
  59. gflow_cli-0.12.0/scripts/dev/spike_patch_entity.py +244 -0
  60. gflow_cli-0.12.0/skills/README.md +76 -0
  61. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/skills/gflow-cli/SKILL.md +80 -1
  62. gflow_cli-0.12.0/skills/plan/SKILL.md +215 -0
  63. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/skills/pr-council-review/SKILL.md +1 -0
  64. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/skills/predict/SKILL.md +1 -0
  65. gflow_cli-0.12.0/skills/status/SKILL.md +99 -0
  66. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/src/gflow_cli/__init__.py +1 -1
  67. gflow_cli-0.12.0/src/gflow_cli/api/_sapisidhash.py +15 -0
  68. gflow_cli-0.12.0/src/gflow_cli/api/character.py +261 -0
  69. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/src/gflow_cli/api/client.py +647 -18
  70. gflow_cli-0.12.0/src/gflow_cli/api/routes.py +132 -0
  71. gflow_cli-0.12.0/src/gflow_cli/api/scene.py +172 -0
  72. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/src/gflow_cli/api/transports/experimental/sapisidhash.py +1 -8
  73. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/src/gflow_cli/api/transports/ui_automation.py +553 -55
  74. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/src/gflow_cli/api/transports/ui_automation_video.py +357 -26
  75. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/src/gflow_cli/api/video.py +23 -0
  76. gflow_cli-0.12.0/src/gflow_cli/chain.py +307 -0
  77. gflow_cli-0.12.0/src/gflow_cli/chain_manifest.py +138 -0
  78. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/src/gflow_cli/cli.py +4 -0
  79. gflow_cli-0.12.0/src/gflow_cli/cli_character.py +379 -0
  80. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/src/gflow_cli/cli_data.py +6 -3
  81. gflow_cli-0.12.0/src/gflow_cli/cli_scene.py +239 -0
  82. gflow_cli-0.12.0/src/gflow_cli/cli_video.py +1030 -0
  83. gflow_cli-0.12.0/src/gflow_cli/data/chain_repo.py +128 -0
  84. gflow_cli-0.12.0/src/gflow_cli/data/migrations/0003_add_scene_tables.sql +29 -0
  85. gflow_cli-0.12.0/src/gflow_cli/data/migrations/0004_add_scene_output_path.sql +5 -0
  86. gflow_cli-0.12.0/src/gflow_cli/data/migrations/0005_add_chain_links.sql +27 -0
  87. gflow_cli-0.12.0/src/gflow_cli/data/migrations/0006_add_operations_metadata.sql +5 -0
  88. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/src/gflow_cli/data/models.py +53 -0
  89. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/src/gflow_cli/data/recorder.py +324 -21
  90. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/src/gflow_cli/data/repository.py +330 -4
  91. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/src/gflow_cli/errors.py +184 -0
  92. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/src/gflow_cli/json_output.py +13 -2
  93. gflow_cli-0.12.0/src/gflow_cli/media.py +120 -0
  94. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/src/gflow_cli/paths.py +21 -0
  95. gflow_cli-0.12.0/src/gflow_cli/services/__init__.py +6 -0
  96. gflow_cli-0.12.0/src/gflow_cli/services/character_create.py +299 -0
  97. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tasks/lessons.md +1 -1
  98. gflow_cli-0.12.0/tests/api/fixtures/character_gen_response.json +54 -0
  99. gflow_cli-0.12.0/tests/api/fixtures/patch_entity_response.json +13 -0
  100. gflow_cli-0.12.0/tests/api/test_aisandbox_auth_error.py +25 -0
  101. gflow_cli-0.12.0/tests/api/test_aisandbox_auth_headers.py +120 -0
  102. gflow_cli-0.12.0/tests/api/test_bearer_redaction.py +74 -0
  103. gflow_cli-0.12.0/tests/api/test_character.py +402 -0
  104. gflow_cli-0.12.0/tests/api/test_client_character.py +307 -0
  105. gflow_cli-0.12.0/tests/api/test_client_generate_character.py +429 -0
  106. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/api/test_client_image.py +5 -5
  107. gflow_cli-0.12.0/tests/api/test_client_patch_entity.py +158 -0
  108. gflow_cli-0.12.0/tests/api/test_client_scene.py +241 -0
  109. gflow_cli-0.12.0/tests/api/test_post_json_aisandbox_auth.py +131 -0
  110. gflow_cli-0.12.0/tests/api/test_routes_character.py +20 -0
  111. gflow_cli-0.12.0/tests/api/test_routes_scene.py +47 -0
  112. gflow_cli-0.12.0/tests/api/test_sapisidhash_helper.py +14 -0
  113. gflow_cli-0.12.0/tests/api/test_scene_models.py +120 -0
  114. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/api/test_video.py +24 -0
  115. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/api/transports/test_ui_automation.py +521 -0
  116. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/api/transports/test_ui_automation_video.py +290 -2
  117. gflow_cli-0.12.0/tests/api/transports/test_ui_character_editor.py +912 -0
  118. gflow_cli-0.12.0/tests/cli/test_cli_character.py +275 -0
  119. gflow_cli-0.12.0/tests/cli/test_cli_character_create.py +613 -0
  120. gflow_cli-0.12.0/tests/cli/test_cli_scene.py +160 -0
  121. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/cli/test_cli_video.py +107 -0
  122. gflow_cli-0.12.0/tests/cli/test_cli_video_chain.py +373 -0
  123. gflow_cli-0.12.0/tests/data/test_chain_repo.py +221 -0
  124. gflow_cli-0.12.0/tests/data/test_find_incomplete_character.py +217 -0
  125. gflow_cli-0.12.0/tests/data/test_models.py +24 -0
  126. gflow_cli-0.12.0/tests/data/test_recorder_character.py +254 -0
  127. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/data/test_repository.py +66 -10
  128. gflow_cli-0.12.0/tests/data/test_scene_persistence.py +148 -0
  129. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/data/test_store_migrations.py +1 -1
  130. gflow_cli-0.12.0/tests/e2e/test_aisandbox_auth_live.py +72 -0
  131. gflow_cli-0.12.0/tests/e2e/test_chain_e2e.py +198 -0
  132. gflow_cli-0.12.0/tests/e2e/test_character_create_e2e.py +442 -0
  133. gflow_cli-0.12.0/tests/e2e/test_scene_compose_live.py +103 -0
  134. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/e2e/test_transports_e2e.py +236 -2
  135. gflow_cli-0.12.0/tests/features/character_create.feature +34 -0
  136. gflow_cli-0.12.0/tests/features/character_read.feature +10 -0
  137. gflow_cli-0.12.0/tests/features/test_character_create_steps.py +288 -0
  138. gflow_cli-0.12.0/tests/features/test_character_read_steps.py +171 -0
  139. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/features/test_step_collision_guard.py +2 -0
  140. gflow_cli-0.12.0/tests/features/test_video_chain_steps.py +291 -0
  141. gflow_cli-0.12.0/tests/features/video_chain.feature +37 -0
  142. gflow_cli-0.12.0/tests/services/test_character_create_redaction.py +312 -0
  143. gflow_cli-0.12.0/tests/services/test_character_create_saga.py +442 -0
  144. gflow_cli-0.12.0/tests/services/test_character_gen_no_direct_post.py +243 -0
  145. gflow_cli-0.12.0/tests/smoke/__init__.py +0 -0
  146. gflow_cli-0.12.0/tests/test_chain.py +372 -0
  147. gflow_cli-0.12.0/tests/test_chain_manifest.py +243 -0
  148. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/test_errors.py +70 -0
  149. gflow_cli-0.12.0/tests/test_errors_403.py +19 -0
  150. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/test_marker_registry.py +1 -1
  151. gflow_cli-0.12.0/tests/test_media.py +158 -0
  152. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/test_paths.py +18 -0
  153. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/uv.lock +121 -2
  154. gflow_cli-0.10.0/.claude/commands/gflow/plan.md +0 -39
  155. gflow_cli-0.10.0/.claude/commands/gflow/release.md +0 -168
  156. gflow_cli-0.10.0/skills/README.md +0 -36
  157. gflow_cli-0.10.0/src/gflow_cli/api/routes.py +0 -64
  158. gflow_cli-0.10.0/src/gflow_cli/cli_video.py +0 -554
  159. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/.claude/commands/gflow/branch-review.md +0 -0
  160. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/.claude/commands/gflow/changelog.md +0 -0
  161. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/.claude/commands/gflow/check.md +0 -0
  162. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/.claude/commands/gflow/doc-review.md +0 -0
  163. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/.claude/commands/gflow/known-issues.md +0 -0
  164. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/.claude/commands/gflow/pr-council-review.md +0 -0
  165. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/.claude/commands/gflow/scenario.md +0 -0
  166. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/.continue-here.md +0 -0
  167. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/.env.template +0 -0
  168. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/.gitattributes +0 -0
  169. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/.github/CODEOWNERS +0 -0
  170. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  171. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/.github/copilot-instructions.md +0 -0
  172. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/.github/dependabot.yml +0 -0
  173. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/.github/workflows/ci.yml +0 -0
  174. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/.github/workflows/external-pr-triage.yml +0 -0
  175. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/.github/workflows/release.yml +0 -0
  176. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/.gitleaks.toml +0 -0
  177. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/.planning/todos/pending/2026-05-11-add-project-logo-and-docs-site-promotion-plan.md +0 -0
  178. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/.planning/todos/pending/pr-38-review.md +0 -0
  179. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/.pre-commit-config.yaml +0 -0
  180. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/.secrets.baseline +0 -0
  181. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/CONFIGURATION.md +0 -0
  182. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/CONTRIBUTING.md +0 -0
  183. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/DISCLAIMER.md +0 -0
  184. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/LICENSE +0 -0
  185. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/RELEASE.md +0 -0
  186. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/ROADMAP.md +0 -0
  187. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/conftest.py +0 -0
  188. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docker-compose.yml +0 -0
  189. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docs/ARCHITECTURE.md +0 -0
  190. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docs/AUTHENTICATION.md +0 -0
  191. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docs/DATA_LAYER.md +0 -0
  192. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docs/DEBUGGING.md +0 -0
  193. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docs/DEVELOPMENT.md +0 -0
  194. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docs/E2E_TESTING.md +0 -0
  195. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docs/EXTERNAL_STORAGE.md +0 -0
  196. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docs/GITHUB.md +0 -0
  197. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docs/LIVE_VERIFICATION_data_layer.md +0 -0
  198. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docs/LIVE_VERIFICATION_image_batch.md +0 -0
  199. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docs/LIVE_VERIFICATION_v0.10.0.md +0 -0
  200. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docs/LIVE_VERIFICATION_v0.7.0.md +0 -0
  201. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docs/LIVE_VERIFICATION_v0.8.1.md +0 -0
  202. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docs/LIVE_VERIFICATION_v0.9.0.md +0 -0
  203. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docs/LIVE_VERIFICATION_v0.9.1.md +0 -0
  204. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docs/LIVE_VERIFICATION_video_download.md +0 -0
  205. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docs/SECURITY.md +0 -0
  206. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docs/USER_GUIDE.md +0 -0
  207. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docs/assets/example-run.gif +0 -0
  208. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docs/superpowers/2026-05-17-issue-15-handover.md +0 -0
  209. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docs/superpowers/plans/2026-05-09-image-mvp-orchestration.md +0 -0
  210. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docs/superpowers/plans/2026-05-09-image-mvp.md +0 -0
  211. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docs/superpowers/plans/2026-05-09-video-mvp-orchestration.md +0 -0
  212. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docs/superpowers/plans/2026-05-09-video-mvp.md +0 -0
  213. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docs/superpowers/plans/2026-05-10-phase-4-hardening-orchestration.md +0 -0
  214. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docs/superpowers/plans/2026-05-10-phase-4-hardening.md +0 -0
  215. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docs/superpowers/plans/2026-05-14-shell-multi-prompt/2026-05-14-shell-multi-prompt-orchestration.md +0 -0
  216. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docs/superpowers/plans/2026-05-14-shell-multi-prompt/COUNCIL_FINAL_ARCH.md +0 -0
  217. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docs/superpowers/plans/2026-05-14-shell-multi-prompt/COUNCIL_FINAL_SEC_UX.md +0 -0
  218. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docs/superpowers/plans/2026-05-14-shell-multi-prompt/COUNCIL_REVIEW_CODE.md +0 -0
  219. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docs/superpowers/plans/2026-05-14-shell-multi-prompt/COUNCIL_REVIEW_GEMINI.md +0 -0
  220. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docs/superpowers/plans/2026-05-14-shell-multi-prompt/COUNCIL_REVIEW_SECURITY.md +0 -0
  221. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docs/superpowers/plans/2026-05-14-shell-multi-prompt/IMPLEMENTATION_REVIEW_PYTHON.md +0 -0
  222. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docs/superpowers/plans/2026-05-14-shell-multi-prompt/IMPLEMENTATION_REVIEW_SECURITY.md +0 -0
  223. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docs/superpowers/plans/2026-05-14-shell-multi-prompt/PLAN.md +0 -0
  224. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docs/superpowers/plans/2026-05-14-shell-multi-prompt/PLAN_REVIEW_CODE.md +0 -0
  225. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docs/superpowers/plans/2026-05-14-shell-multi-prompt/PLAN_REVIEW_FOLLOWUP.md +0 -0
  226. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docs/superpowers/plans/2026-05-14-shell-multi-prompt/PLAN_REVIEW_PLANNER.md +0 -0
  227. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docs/superpowers/plans/2026-05-14-shell-multi-prompt/PLAN_REVIEW_SECURITY.md +0 -0
  228. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docs/superpowers/plans/2026-05-14-shell-multi-prompt/PLAN_REVIEW_SECURITY_FOLLOWUP.md +0 -0
  229. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docs/superpowers/plans/2026-05-15-auth-login-real-chrome/COUNCIL_FINAL_SEC_UX_VERIFIED.md +0 -0
  230. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docs/superpowers/plans/2026-05-15-auth-login-real-chrome/COUNCIL_REVIEW_PLAN_SECURITY.md +0 -0
  231. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docs/superpowers/plans/2026-05-15-auth-login-real-chrome/COUNCIL_REVIEW_SPEC_SECURITY.md +0 -0
  232. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docs/superpowers/plans/2026-05-15-auth-login-real-chrome/PLAN.md +0 -0
  233. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docs/superpowers/plans/2026-05-15-auth-login-real-chrome/orchestration.md +0 -0
  234. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docs/superpowers/plans/2026-05-17-e2e-test-coverage.md +0 -0
  235. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docs/superpowers/plans/2026-05-17-issue-15-auth-verification-fix.md +0 -0
  236. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docs/superpowers/plans/2026-05-17-issue-15-i2v-bearer-auth.md +0 -0
  237. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docs/superpowers/plans/2026-05-17-issue-15-orchestration.md +0 -0
  238. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docs/superpowers/plans/2026-05-18-video-phase0-submit-spike.md +0 -0
  239. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docs/superpowers/plans/2026-05-19-video-phase-a-execution-state.md +0 -0
  240. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docs/superpowers/plans/2026-05-19-video-phase-a-orchestration.md +0 -0
  241. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docs/superpowers/plans/2026-05-19-video-phase-a-t2v.md +0 -0
  242. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docs/superpowers/plans/2026-05-20-video-download-t2v-cli.md +0 -0
  243. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docs/superpowers/plans/2026-05-21-multi-image-prompt-orchestration.md +0 -0
  244. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docs/superpowers/plans/2026-05-21-multi-image-prompt.md +0 -0
  245. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docs/superpowers/plans/2026-05-22-pr-38-review.md +0 -0
  246. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docs/superpowers/plans/2026-05-22-stay-mounted-batch-session-plan.md +0 -0
  247. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docs/superpowers/plans/2026-05-23-locale-agnostic-selectors.md +0 -0
  248. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docs/superpowers/plans/2026-05-24-data-layer.md +0 -0
  249. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docs/superpowers/specs/2026-05-10-phase-4-hardening-design.md +0 -0
  250. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docs/superpowers/specs/2026-05-14-shell-multi-prompt-design.md +0 -0
  251. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docs/superpowers/specs/2026-05-15-auth-login-real-chrome-design.md +0 -0
  252. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docs/superpowers/specs/2026-05-17-e2e-test-coverage-design.md +0 -0
  253. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docs/superpowers/specs/2026-05-17-i2v-uploadimage-401-bearer-auth-design.md +0 -0
  254. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docs/superpowers/specs/2026-05-17-issue-15-auth-verification-fix-design.md +0 -0
  255. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docs/superpowers/specs/2026-05-17-issue-15-root-cause-findings.md +0 -0
  256. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docs/superpowers/specs/2026-05-18-ui-automation-video-generation-design.md +0 -0
  257. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docs/superpowers/specs/2026-05-21-multi-image-prompt-design.md +0 -0
  258. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docs/superpowers/specs/2026-05-22-pr-38-review-design.md +0 -0
  259. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docs/superpowers/specs/2026-05-22-stay-mounted-batch-session-design.md +0 -0
  260. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docs/superpowers/specs/2026-05-23-locale-agnostic-selectors.md +0 -0
  261. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docs/superpowers/specs/2026-05-23-readme-v0.8.1-refresh-design.md +0 -0
  262. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docs/superpowers/specs/2026-05-24-data-layer-design.md +0 -0
  263. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docs/superpowers/specs/2026-05-27-public-event-surface-design.md +0 -0
  264. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/docs/superpowers/verifications/2026-05-11-phase-4-stage-g.md +0 -0
  265. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/examples/batch_from_config.py +0 -0
  266. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/examples/multi_prompt_t2i.py +0 -0
  267. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/examples/sample_config.json +0 -0
  268. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/examples/sample_prompts.txt +0 -0
  269. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/examples/single_image_t2i.py +0 -0
  270. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/samples/README.md +0 -0
  271. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/samples/captured/01_upload_image.json +0 -0
  272. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/samples/captured/02_batchAsyncGenerateVideoText.json +0 -0
  273. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/samples/captured/03_batchCheckAsyncVideoGenerationStatus.json +0 -0
  274. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/samples/captured/04_archive_workflow.json +0 -0
  275. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/samples/captured/05_createProject.json +0 -0
  276. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/samples/captured/06_batchGenerateImages.json +0 -0
  277. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/samples/captured/07_batchGenerateImages_seeded.json +0 -0
  278. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/samples/captured/08_batchAsyncGenerateVideoStartAndEndImage.json +0 -0
  279. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/samples/captured/09_batchAsyncGenerateVideoReferenceImages.json +0 -0
  280. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/samples/captured/10_batchCheckAsyncVideoGenerationStatus_successful.json +0 -0
  281. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/samples/captured/11_batchCheckAsyncVideoGenerationStatus_failed.json +0 -0
  282. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/scripts/ci/check_repo_hygiene.py +0 -0
  283. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/scripts/debug_editor.py +0 -0
  284. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/scripts/debug_gen_settings.py +0 -0
  285. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/scripts/debug_settings.py +0 -0
  286. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/scripts/dev/capture_i2v_frame_slots_dom.py +0 -0
  287. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/scripts/dev/capture_image_add_media_dom.py +0 -0
  288. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/scripts/dev/capture_locale_invariants.py +0 -0
  289. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/scripts/dev/cdp_drive_and_probe.py +0 -0
  290. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/scripts/dev/monitor_pr_38.py +0 -0
  291. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/scripts/diag_capture_flow_traffic.py +0 -0
  292. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/scripts/diag_recaptcha_mint.py +0 -0
  293. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/scripts/record_demo.ps1 +0 -0
  294. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/scripts/smoke_image.py +0 -0
  295. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/scripts/smoke_real_chrome_image.py +0 -0
  296. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/scripts/smoke_video_editor.py +0 -0
  297. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/scripts/smoke_worker_style.py +0 -0
  298. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/scripts/verify_chrome_auth_viability.py +0 -0
  299. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/skills/scenario/SKILL.md +0 -0
  300. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/sonar-project.properties +0 -0
  301. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/src/gflow_cli/__main__.py +0 -0
  302. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/src/gflow_cli/_cli_helpers.py +0 -0
  303. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/src/gflow_cli/api/__init__.py +0 -0
  304. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/src/gflow_cli/api/_retry.py +0 -0
  305. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/src/gflow_cli/api/dto.py +0 -0
  306. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/src/gflow_cli/api/image.py +0 -0
  307. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/src/gflow_cli/api/recaptcha.py +0 -0
  308. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/src/gflow_cli/api/transports/__init__.py +0 -0
  309. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/src/gflow_cli/api/transports/_common.py +0 -0
  310. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/src/gflow_cli/api/transports/_fingerprint.py +0 -0
  311. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/src/gflow_cli/api/transports/base.py +0 -0
  312. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/src/gflow_cli/api/transports/experimental/__init__.py +0 -0
  313. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/src/gflow_cli/api/transports/experimental/bearer.py +0 -0
  314. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/src/gflow_cli/api/transports/experimental/evaluate_fetch.py +0 -0
  315. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/src/gflow_cli/auth/__init__.py +0 -0
  316. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/src/gflow_cli/auth/base.py +0 -0
  317. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/src/gflow_cli/auth/factory.py +0 -0
  318. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/src/gflow_cli/auth/internal_chromium.py +0 -0
  319. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/src/gflow_cli/auth/real_chrome.py +0 -0
  320. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/src/gflow_cli/auth/strategies.py +0 -0
  321. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/src/gflow_cli/auth/verification.py +0 -0
  322. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/src/gflow_cli/browser_manager.py +0 -0
  323. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/src/gflow_cli/cli_image.py +0 -0
  324. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/src/gflow_cli/cli_models.py +0 -0
  325. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/src/gflow_cli/cli_run.py +0 -0
  326. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/src/gflow_cli/config.py +0 -0
  327. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/src/gflow_cli/data/__init__.py +0 -0
  328. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/src/gflow_cli/data/migrations/0001_initial.sql +0 -0
  329. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/src/gflow_cli/data/migrations/0002_add_cloud_storage.sql +0 -0
  330. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/src/gflow_cli/data/migrations/__init__.py +0 -0
  331. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/src/gflow_cli/data/queries.py +0 -0
  332. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/src/gflow_cli/data/redaction.py +0 -0
  333. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/src/gflow_cli/data/store.py +0 -0
  334. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/src/gflow_cli/exceptions.py +0 -0
  335. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/src/gflow_cli/image_batch.py +0 -0
  336. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/src/gflow_cli/manifest.py +0 -0
  337. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/src/gflow_cli/observability.py +0 -0
  338. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/src/gflow_cli/profile_store.py +0 -0
  339. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/src/gflow_cli/storage.py +0 -0
  340. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/test_assets/sample_batch.json +0 -0
  341. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/test_assets/sample_batch.tsv +0 -0
  342. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/test_assets/sample_batch_invalid.tsv +0 -0
  343. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/__init__.py +0 -0
  344. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/api/__init__.py +0 -0
  345. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/api/test_client.py +0 -0
  346. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/api/test_concurrency.py +0 -0
  347. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/api/test_dto.py +0 -0
  348. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/api/test_image.py +0 -0
  349. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/api/test_image_dto.py +0 -0
  350. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/api/test_recaptcha.py +0 -0
  351. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/api/test_retry.py +0 -0
  352. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/api/test_routes.py +0 -0
  353. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/api/transports/__init__.py +0 -0
  354. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/api/transports/test_base.py +0 -0
  355. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/api/transports/test_bearer.py +0 -0
  356. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/api/transports/test_common.py +0 -0
  357. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/api/transports/test_evaluate_fetch.py +0 -0
  358. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/api/transports/test_factory.py +0 -0
  359. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/api/transports/test_fingerprint.py +0 -0
  360. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/api/transports/test_sapisidhash.py +0 -0
  361. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/api/transports/test_transport_timeout.py +0 -0
  362. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/api/transports/test_ui_automation_batch.py +0 -0
  363. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/api/transports/test_ui_automation_image_mode.py +0 -0
  364. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/auth/strategies/test_factory.py +0 -0
  365. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/auth/strategies/test_strategies.py +0 -0
  366. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/auth/test_verification.py +0 -0
  367. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/cli/__init__.py +0 -0
  368. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/cli/test_cli_auth_list.py +0 -0
  369. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/cli/test_cli_data.py +0 -0
  370. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/cli/test_cli_image.py +0 -0
  371. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/cli/test_cli_image_seed_removed.py +0 -0
  372. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/cli/test_cli_models.py +0 -0
  373. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/cli/test_cli_run.py +0 -0
  374. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/cli/test_error_handling.py +0 -0
  375. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/cli/test_helpers.py +0 -0
  376. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/cli/test_t2i_multi_prompt.py +0 -0
  377. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/conftest.py +0 -0
  378. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/data/__init__.py +0 -0
  379. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/data/test_packaging.py +0 -0
  380. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/data/test_recorder.py +0 -0
  381. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/data/test_redaction.py +0 -0
  382. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/data/test_settings_and_errors.py +0 -0
  383. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/e2e/__init__.py +0 -0
  384. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/e2e/conftest.py +0 -0
  385. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/e2e/test_auth_verification_e2e.py +0 -0
  386. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/e2e/test_data_layer_e2e.py +0 -0
  387. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/e2e/test_image_batch_e2e.py +0 -0
  388. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/e2e/test_image_i2i_ref_cap_e2e.py +0 -0
  389. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/e2e/test_json_output_e2e.py +0 -0
  390. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/e2e/test_locale_selectors_e2e.py +0 -0
  391. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/e2e/test_video_r2v_ref_cap_e2e.py +0 -0
  392. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/e2e/test_video_t2v_e2e.py +0 -0
  393. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/features/__init__.py +0 -0
  394. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/features/auth.feature +0 -0
  395. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/features/auth_login.feature +0 -0
  396. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/features/conftest.py +0 -0
  397. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/features/image.feature +0 -0
  398. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/features/test_auth_login_steps.py +0 -0
  399. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/features/test_auth_steps.py +0 -0
  400. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/features/test_image_steps.py +0 -0
  401. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/fixtures/__init__.py +0 -0
  402. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/fixtures/seeded_catalog.py +0 -0
  403. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/image_batch/__init__.py +0 -0
  404. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/image_batch/test_image_manifest.py +0 -0
  405. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/image_batch/test_observability_events.py +0 -0
  406. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/integration/__init__.py +0 -0
  407. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/integration/conftest.py +0 -0
  408. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/integration/constants.py +0 -0
  409. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/integration/test_storage_gcs.py +0 -0
  410. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/integration/test_storage_s3.py +0 -0
  411. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/scripts/test_capture_locale_invariants.py +0 -0
  412. {gflow_cli-0.10.0/tests/smoke → gflow_cli-0.12.0/tests/services}/__init__.py +0 -0
  413. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/smoke/test_profile_account_smoke.py +0 -0
  414. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/smoke/test_real_flow.py +0 -0
  415. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/test_auth.py +0 -0
  416. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/test_browser_manager.py +0 -0
  417. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/test_cli_data.py +0 -0
  418. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/test_config.py +0 -0
  419. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/test_conftest_isolation.py +0 -0
  420. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/test_data_queries.py +0 -0
  421. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/test_documentation_gate.py +0 -0
  422. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/test_json_output.py +0 -0
  423. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/test_manifest.py +0 -0
  424. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/test_observability.py +0 -0
  425. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/test_profile_store.py +0 -0
  426. {gflow_cli-0.10.0 → gflow_cli-0.12.0}/tests/test_smoke.py +0 -0
@@ -12,7 +12,10 @@ This directory holds **internal maintainer workflows** that are bundled with the
12
12
  └── commands/ ← repo-local slash commands
13
13
  └── gflow/ ← `/gflow:*` namespace (avoids collision with built-ins)
14
14
  ├── check.md ← `/gflow:check` — hygiene + ruff + pyright + pytest
15
- ├── plan.md ← `/gflow:plan` — show active phase / superpowers plan
15
+ ├── status.md ← `/gflow:status` — full plan state (file, goal, progress, next task)
16
+ ├── next.md ← `/gflow:next` — next unchecked task only
17
+ ├── active.md ← `/gflow:active` — which plan is active, goal only
18
+ ├── plan.md ← `/gflow:plan <feature>` — create a task-by-task implementation plan
16
19
  ├── known-issues.md← `/gflow:known-issues` — open/mitigated items
17
20
  ├── changelog.md ← `/gflow:changelog` — [Unreleased] + last tagged
18
21
  └── release.md ← `/gflow:release` — full release flow (signed tags)
@@ -0,0 +1,13 @@
1
+ ---
2
+ description: Show which plan is active and its goal — orientation without task detail.
3
+ ---
4
+
5
+ # `/gflow:active` — Active plan identity
6
+
7
+ **Read `skills/status/SKILL.md` and follow the `active` variant protocol.**
8
+
9
+ > Do **not** call `Skill(skill="status")` — read the file directly.
10
+
11
+ The skill at `skills/status/SKILL.md` runs `scripts/dev/active_plan.py` and returns
12
+ only the header lines (Plan path, Title, Goal, Progress count). Stops before the
13
+ `--- Next task ---` separator.
@@ -0,0 +1,12 @@
1
+ ---
2
+ description: Show only the next unchecked task — minimal output, no context noise.
3
+ ---
4
+
5
+ # `/gflow:next [feature]` — Next task
6
+
7
+ **Read `skills/status/SKILL.md` and follow the `next` variant protocol**, passing `$ARGUMENTS` as the optional feature slug.
8
+
9
+ > Do **not** call `Skill(skill="status")` — read the file directly.
10
+
11
+ The skill at `skills/status/SKILL.md` runs `scripts/dev/active_plan.py` and returns
12
+ only the `--- Next task ---` block. Header lines (Plan, Title, Goal, Progress) are omitted.
@@ -0,0 +1,22 @@
1
+ ---
2
+ description: Create a structured task-by-task implementation plan for a feature and write it to docs/superpowers/plans/.
3
+ ---
4
+
5
+ # `/gflow:plan <feature>` — Create a feature plan
6
+
7
+ **Read `skills/plan/SKILL.md` and follow its protocol now**, passing `$ARGUMENTS` as the feature description.
8
+
9
+ > Do **not** call `Skill(skill="plan")` — the repo's `skills/*/SKILL.md` files are plain Markdown, not registered as Skill-tool-invocable. Read the file directly instead.
10
+
11
+ The skill at `skills/plan/SKILL.md` gathers predict/scenario context, asks ≤3
12
+ clarifying questions, decomposes the feature into atomic committable tasks with
13
+ step + test checklists, and writes `docs/superpowers/plans/<date>-<slug>/PLAN.md`.
14
+
15
+ **Typical workflow:**
16
+ ```
17
+ /gflow:predict <proposal> → GO / CAUTION / STOP
18
+ /gflow:scenario <feature> → edge cases + BDD skeleton
19
+ /gflow:plan <feature> → writes PLAN.md ← this command
20
+ /gflow:status → surfaces next task
21
+ /gflow:check → before each commit
22
+ ```
@@ -16,4 +16,10 @@ The skill at `skills/predict/SKILL.md` runs five independent expert personas
16
16
  (Architect · Security/reCAPTCHA · Performance/Playwright · CLI UX · Devil's Advocate),
17
17
  resolves conflicts, and returns a GO / CAUTION / STOP verdict with a confidence score.
18
18
 
19
- **Pair with `/gflow:scenario`** after a GO or CAUTION to enumerate edge cases before EXECUTE.
19
+ **Typical workflow after a GO or CAUTION:**
20
+ ```
21
+ /gflow:scenario <feature> → edge cases + BDD skeleton
22
+ /gflow:plan <feature> → writes PLAN.md task checklist
23
+ /gflow:status → surfaces next task during execution
24
+ /gflow:check → before each commit
25
+ ```
@@ -0,0 +1,241 @@
1
+ ---
2
+ description: Cut a new gflow-cli release — bump version, update CHANGELOG, tag, push, and back-merge.
3
+ ---
4
+
5
+ # `/gflow:release` — Cut a new release
6
+
7
+ Follow this sequence verbatim. Every step matters.
8
+
9
+ > **Branch-protection note:** `main` blocks direct pushes. The release commit travels
10
+ > via a `chore/release-vX.Y.Z` branch PR. The signed tag is pushed independently
11
+ > (tag pushes bypass branch protection and trigger the CI release workflow immediately).
12
+ >
13
+ > **Source-branch note (read first):** `develop` is the integration branch — it carries
14
+ > ALL unreleased work and `main` usually lags it. The release branch is cut from
15
+ > **`develop`**, NOT `main`. The PR `chore/release-vX.Y.Z → main` then brings the full
16
+ > integration history onto `main`. Do not expect the work to already be on `main`.
17
+
18
+ ## Inputs
19
+
20
+ Ask the user (if not already provided):
21
+
22
+ 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).
23
+ 2. **Pre-release?** — prerelease versions stay marked as GitHub prereleases. Only the user can say when a release line is ready for the stable tag.
24
+
25
+ ---
26
+
27
+ ## Sequence
28
+
29
+ **1. Review what's queued.**
30
+
31
+ Run `/gflow:changelog` — confirm the `[Unreleased]` block is non-empty and accurate before proceeding.
32
+
33
+ **2. Verify (or triage) a clean working tree.**
34
+
35
+ ```bash
36
+ git status --short
37
+ ```
38
+
39
+ If empty, continue. If not, **triage before aborting** — do not blindly stop:
40
+
41
+ - **Auto-injected boilerplate** (e.g. a context-mode routing block appended to
42
+ `CLAUDE.md` by an MCP plugin's SessionStart hook): this is plugin-injected, not
43
+ project content — `git restore` it. Confirm with the user if unsure.
44
+ - **Build/temp artifacts** (e.g. a stray `tmp*.tar.gz` sdist at repo root): delete them.
45
+ - **Genuine uncommitted work:** STOP and tell the user to commit or stash on the
46
+ appropriate branch (never commit straight to `develop`).
47
+
48
+ The tree must be clean before you create the release branch.
49
+
50
+ **3. Verify `develop` is the release source and up-to-date.**
51
+
52
+ The release is cut from `develop`, NOT `main` (see Source-branch note above).
53
+ Confirm direction explicitly — a backwards divergence means a prior back-merge was skipped.
54
+
55
+ ```bash
56
+ git fetch origin
57
+ git rev-parse --abbrev-ref HEAD # expect "develop"
58
+ git rev-list --count HEAD..origin/develop # local behind origin — expect 0
59
+ git rev-list --count origin/main..origin/develop # develop AHEAD of main — expect > 0 (the work to release)
60
+ git rev-list --count origin/develop..origin/main # main AHEAD of develop — expect 0
61
+ ```
62
+
63
+ If not on `develop`: `git checkout develop && git pull origin develop`.
64
+ If local is behind origin: `git pull origin develop`.
65
+ **If `main` is AHEAD of `develop` (last count > 0): STOP.** A prior release skipped its
66
+ `main → develop` back-merge — recover first (see the `release-back-merge-gap-recovery`
67
+ memory) or the release branch will hit conflicts on `pyproject.toml` / `__init__.py` / `CHANGELOG.md`.
68
+
69
+ **4. Run quality gates.**
70
+
71
+ Run `/gflow:check` — all gates must pass. Abort if any fail.
72
+
73
+ **5. Create a release branch off `develop`.**
74
+
75
+ ```bash
76
+ git checkout develop # ensure the base is develop, not main
77
+ git checkout -b chore/release-v<NEW_VERSION>
78
+ ```
79
+
80
+ This branch now contains all of `develop` (⊇ `main`) plus your release prep. All
81
+ release prep commits live here; the PR into `main` (step 14) carries the full
82
+ integration history forward.
83
+
84
+ **6. Bump version** in `pyproject.toml`:
85
+
86
+ ```toml
87
+ [project]
88
+ version = "<NEW_VERSION>"
89
+ ```
90
+
91
+ **7. Bump package version** in `src/gflow_cli/__init__.py`:
92
+
93
+ ```python
94
+ __version__ = "<NEW_VERSION>"
95
+ ```
96
+
97
+ **8. Update version assertion tests** if present:
98
+
99
+ ```bash
100
+ rg -n "__version__|<OLD_VERSION>|version assertion" tests src pyproject.toml
101
+ ```
102
+
103
+ **9. Migrate CHANGELOG.**
104
+
105
+ - Move all entries under `## [Unreleased]` to a new `## [<NEW_VERSION>] — YYYY-MM-DD` section.
106
+ - Leave `## [Unreleased]` empty.
107
+ - Update the link footer. Match the repo's existing convention — every prior entry
108
+ uses the `compare/vPREV...vNEW` form, so use that for the new version too (NOT the
109
+ `releases/tag/` form), or `/gflow:doc-review` will flag the inconsistency:
110
+ ```
111
+ [Unreleased]: https://github.com/ffroliva/gflow-cli/compare/v<NEW_VERSION>...HEAD
112
+ [<NEW_VERSION>]: https://github.com/ffroliva/gflow-cli/compare/v<PREV_VERSION>...v<NEW_VERSION>
113
+ ```
114
+
115
+ **10. Run the documentation review gate.**
116
+
117
+ Run `/gflow:doc-review` — audit all version refs, INDEX completeness, evidence files, skill files, CHANGELOG footer, and memory files. Fix every **FAIL** before continuing. Fold all discovered fixes into the release prep commit.
118
+
119
+ **11. Commit the release prep.**
120
+
121
+ ```bash
122
+ git add pyproject.toml src/gflow_cli/__init__.py uv.lock CHANGELOG.md
123
+ git add docs/ .claude/commands/gflow/ # include any doc-review fixes
124
+ # doc-review version-currency fixes often also touch ROOT docs — stage them too:
125
+ git add README.md PLAN.md KNOWN_ISSUES.md AGENTS.md llms.txt 2>/dev/null || true
126
+ git status --short # review EVERYTHING staged before committing
127
+ git commit -m "chore(release): v<NEW_VERSION>"
128
+ ```
129
+
130
+ - **`uv.lock` changes** on every version bump (the editable package version is
131
+ pinned in the lockfile) — it is easy to forget and must ship in this commit.
132
+ - The release-prep commit must NOT carry a `Co-Authored-By` trailer (see reminders).
133
+
134
+ **12. Tag the release commit.** Use `-s` for a signed annotated tag so GitHub shows **"Verified"** AND `.github/workflows/release.yml` passes the signed-tag gate (unsigned or lightweight tags are rejected by CI).
135
+
136
+ ```bash
137
+ git tag -s v<NEW_VERSION> -m "v<NEW_VERSION>"
138
+ ```
139
+
140
+ Signing requirements:
141
+ - **SSH signing (preferred):** `git config --global gpg.format ssh` + `user.signingkey` pointing at your public key.
142
+ - **GPG:** any registered GPG key works.
143
+ - Run `git config --global user.signingkey` to confirm a key is configured.
144
+
145
+ Confirm the tag actually carries a signature (this is what CI checks):
146
+
147
+ ```bash
148
+ git cat-file -p v<NEW_VERSION> | grep -c "BEGIN SSH SIGNATURE" # expect 1 (or "BEGIN PGP SIGNATURE" for GPG)
149
+ ```
150
+
151
+ > **Benign local-verify error:** `git tag -v v<NEW_VERSION>` may fail with
152
+ > `gpg.ssh.allowedSignersFile needs to be configured`. This is a *local
153
+ > verification-config* gap only — the tag IS validly signed and CI still passes
154
+ > (CI greps for the signature header, above). To make local verify work once and
155
+ > for all, create an allowed-signers file (`<your-email> ssh-rsa AAAA...`) and run
156
+ > `git config --global gpg.ssh.allowedSignersFile <path>`. See the `release-signing`
157
+ > memory for the exact recipe. Do NOT treat this error as a signing failure.
158
+
159
+ **13. Push the tag first** (bypasses branch protection; triggers the CI release workflow immediately):
160
+
161
+ > **⚠ POINT OF NO RETURN — confirm with the user before this push.** Pushing the
162
+ > tag immediately triggers `.github/workflows/release.yml` → **PyPI publish +
163
+ > public GitHub Release**. A pushed release tag must NOT be force-replaced (ship a
164
+ > PATCH instead). Get an explicit go-ahead, then push.
165
+
166
+ ```bash
167
+ git push origin v<NEW_VERSION>
168
+ ```
169
+
170
+ CI will start building the release. Watch <https://github.com/ffroliva/gflow-cli/actions>.
171
+ Wait for the `Release` run to report **completed / success** and confirm the GitHub
172
+ Release published before continuing (`gh release view v<NEW_VERSION>`).
173
+
174
+ **14. Push the release branch and open the PR.**
175
+
176
+ ```bash
177
+ git push -u origin chore/release-v<NEW_VERSION>
178
+ gh pr create --base main --head chore/release-v<NEW_VERSION> \
179
+ --title "chore(release): v<NEW_VERSION>"
180
+ ```
181
+
182
+ Wait for PR CI to go green (`gh pr checks <N> --watch`), then merge with a **merge
183
+ commit** — never squash:
184
+
185
+ ```bash
186
+ gh pr merge <N> --merge --delete-branch
187
+ ```
188
+
189
+ > **NEVER `--squash` this PR.** Because the branch was cut from `develop`, the PR
190
+ > carries the entire batch of unreleased integration commits. A squash collapses
191
+ > them into one opaque commit on `main` and destroys that history. `--merge`
192
+ > preserves it. (The release workflow already ran from the tag push in step 13 —
193
+ > this PR is to bring the bump commit + integration history onto `main`.)
194
+
195
+ **15. Back-merge `main` into `develop`.**
196
+
197
+ After the release PR is merged, bring the bump commit back to `develop` so branches stay aligned:
198
+
199
+ ```bash
200
+ git checkout develop
201
+ git pull origin develop
202
+ git fetch origin main
203
+ git merge origin/main --no-ff -m "chore: back-merge main (v<NEW_VERSION>) into develop"
204
+ git push origin develop
205
+ ```
206
+
207
+ If there are conflicts (rare — only if `develop` has commits that touched the same lines as the bump), resolve them, keeping `develop`'s unreleased work and `main`'s version bump.
208
+
209
+ **16. Report.**
210
+
211
+ Tell the user:
212
+ - Tag push triggered `.github/workflows/release.yml`.
213
+ - Watch <https://github.com/ffroliva/gflow-cli/actions> for the release workflow.
214
+ - On success: PyPI publish + GitHub Release with auto-generated notes.
215
+ - On failure (most common: PyPI Trusted Publishing not yet configured): point to <https://pypi.org/manage/account/publishing/>.
216
+ - `develop` is now synced with `main` (back-merge done in step 15).
217
+ - Next development cycle starts on `develop` — open `## [Unreleased]` in CHANGELOG is ready.
218
+
219
+ ---
220
+
221
+ ## Critical reminders
222
+
223
+ - **ALWAYS** cut the release branch from `develop`, not `main` — `develop` carries the work.
224
+ - **NEVER** `--squash` the release PR into `main` — it destroys the integration history the branch carries. Use `--merge`.
225
+ - **NEVER** skip the `main → develop` back-merge (step 15) — skipping it guarantees conflicts at the next release.
226
+ - **NEVER** add `Co-Authored-By: Claude` (or any AI co-author) to the release commit.
227
+ - **NEVER** force-push a release tag once it's on GitHub. Ship a PATCH fix instead.
228
+ - **NEVER** `--no-verify` past hooks. Fix the underlying issue.
229
+ - **NEVER** push directly to `main` — branch protection will reject it. Always use a PR.
230
+ - A `git tag -v` `allowedSignersFile` error is **benign** (verify-only) — the tag is still signed and CI passes. Don't treat it as a failure.
231
+ - **CONFIRM with the user before the step 13 tag push** — it's the irreversible PyPI + public Release trigger.
232
+ - If quality gates fail at step 4, **STOP**. Surface the failures to the user.
233
+ - If doc-review fails at step 10, **STOP**. Fix before committing.
234
+
235
+ ---
236
+
237
+ ## See also
238
+
239
+ - [RELEASE.md](../../../RELEASE.md) — full release protocol, prerelease policy, and checklist
240
+ - [README § Releases](../../../README.md#releases) — release policy and cadence
241
+ - [PLAN § Phase 5](../../../PLAN.md#phase-5--public-alpha-release-on-pypi) — first-release exit criteria
@@ -0,0 +1,12 @@
1
+ ---
2
+ description: Show current plan state — active plan file, goal, progress, and next unchecked task.
3
+ ---
4
+
5
+ # `/gflow:status [feature]` — Current plan state
6
+
7
+ **Read `skills/status/SKILL.md` and follow the `status` variant protocol**, passing `$ARGUMENTS` as the optional feature slug.
8
+
9
+ > Do **not** call `Skill(skill="status")` — read the file directly.
10
+
11
+ The skill at `skills/status/SKILL.md` runs `scripts/dev/active_plan.py` and returns
12
+ the full output: plan file path, title, goal, progress (X/N), and next task block.
@@ -63,6 +63,9 @@ samples/*.captured.json # sandbox-recorded API exchanges may contain PII
63
63
  test_assets/smoke_*/
64
64
  test_assets/debug_*/
65
65
 
66
+ # Phase-2 live-spike capture outputs — NEVER commit (may contain real API payloads)
67
+ scripts/dev/_spike_out/
68
+
66
69
  # Live Flow traffic captures — NEVER commit (contain real Bearer tokens / API keys).
67
70
  # Diagnostic scripts MUST default-write here, NOT to samples/captured/.
68
71
  # Sanitised reference samples (no secrets) can still live under samples/captured/.
@@ -83,3 +86,6 @@ worktrees/
83
86
 
84
87
  # E2E test logs (live Flow runs — may contain account/profile names)
85
88
  .planning/e2e-logs/
89
+
90
+ # Understand Anything (local knowledge graph)
91
+ .understand-anything/
@@ -0,0 +1,207 @@
1
+ # Issue #125 fix plan — `gflow video i2v` silently routes to T2V with `omni-flash`
2
+
3
+ **Branch:** `bugfix/issue-125-i2v-t2v` (worktree at `.claude/worktrees/bugfix+issue-125-i2v-t2v/`)
4
+ **Issue:** https://github.com/ffroliva/gflow-cli/issues/125
5
+ **Status:** Plan — awaiting 5-persona council review before implementation.
6
+
7
+ ---
8
+
9
+ ## 1. Root cause (confirmed at zero credit)
10
+
11
+ `omni-flash` does NOT support i2v interpolation (start+end frames). Flow's frontend silently drops the bound mediaIds at submit time and routes the request to `batchAsyncGenerateVideoText` with `image_inputs: null`. The user is charged 1 credit for a pure text-to-video generation that ignores the start/end frames entirely.
12
+
13
+ This is **NOT** the originally hypothesised selector / UI-path bug. The "Add to Prompt" click in `_upload_via_open_dialog` IS correct on both EN and pt-BR locales (probe v1). The frame slots transition correctly (`FRAME_SLOTS_STRUCT.count()` drops 2 → 1 → 0, probe v3). The submit-button selector finds the right "Criar" button (probe v3). The bug is at Flow's model-vs-request-shape compatibility check, which is invisible from the DOM.
14
+
15
+ ## 2. Evidence
16
+
17
+ ### Zero-credit evidence
18
+
19
+ | Probe | Sequence | Model | Captured URL | startImage | endImage |
20
+ |---|---|---|---|---|---|
21
+ | v4 prod-order | attaches → prompt → submit | (inherits Flow's last = omni-flash) | `batchAsyncGenerateVideoText` ❌ | `null` | `null` |
22
+ | v4 reorder | prompt → attaches → submit | omni-flash | `batchAsyncGenerateVideoText` ❌ | `null` | `null` |
23
+ | **v5 omni-flash + start+end** | attaches → prompt → submit | omni-flash (explicit) | `batchAsyncGenerateVideoText` ❌ | `null` | `null` |
24
+ | **v5 omni-flash + start-only** | Start only → prompt → submit | omni-flash (explicit) | `batchAsyncGenerateVideoText` ❌ | `null` | `null` |
25
+ | **v5 veo-lite + start+end** | attaches → prompt → submit | **veo-lite** | **`batchAsyncGenerateVideoStartAndEndImage` ✓** | **`4e551690...` ✓** | **`700c5522...` ✓** |
26
+
27
+ **Conclusion: omni-flash does NOT support i2v in ANY form** — neither start-only nor start+end. The strict rejection in §3 is verified, not just conservative.
28
+
29
+ Output dirs:
30
+ - `C:\Users\ffrol\gflow-output\i2v-intercept-prodorder-20260530-160535\evidence.json` (omni-flash, broken)
31
+ - `C:\Users\ffrol\gflow-output\i2v-intercept-veolite-20260530-165432\evidence.json` (veo-lite, correct)
32
+
33
+ ### Human-session HAR evidence
34
+
35
+ `C:\Users\ffrol\Downloads\labs.google14.har` — manual i2v session on the same account, same UI flow as gflow. The captured generate body shows:
36
+
37
+ ```json
38
+ {
39
+ "videoModelKey": "veo_3_1_interpolation_lite", // ← Flow auto-promotes veo_3_1_lite → veo_3_1_interpolation_lite when start+end frames are present
40
+ "startImage": { "mediaId": "3c65f7ed-..." },
41
+ "endImage": { "mediaId": "7e70fd03-..." }
42
+ }
43
+ ```
44
+
45
+ ### Paid run evidence
46
+
47
+ The original gflow paid retry (`C:\Users\ffrol\gflow-output\i2v-prompt-retry-20260530-133705\_err2.log`) used `--model omni-flash` (gflow's default), produced an 8s "wake-up in bedroom" stickman video that has zero visual continuity with `01-t2i.jpg` (stickman at desk) or `02-i2i.jpg` (arms-raised triumph at sunrise). Per the structured-log `generate_captured` event, the request URL was `batchAsyncGenerateVideoText` with all-null image_inputs — pure T2V from the prompt alone.
48
+
49
+ **Retroactive impact:** every i2v paid run on `gflow v0.10.0` with the default model (or `--model omni-flash`) has been a silent T2V. The wf-004 promo "drift" was not Veo style-shift — it was a pure T2V.
50
+
51
+ ## 3. Scope
52
+
53
+ ### In scope (this PR) — council-revised
54
+
55
+ - Add model-vs-mode compatibility helper `VideoModel.supports_i2v_interpolation()` returning False for `OMNI_FLASH`, True for the four `VEO_3_1_*` variants. Add `I2V_DEFAULT_MODEL = VideoModel.VEO_3_1_LITE` module constant in `api/video.py` (domain).
56
+ - **Typed error class** `ModelModeIncompatibilityError` (new, in `gflow_cli.errors`) wired into `EXIT_CODE_MAP` with **exit code 17** (distinct from Click's exit 2 "usage error" and generic exit 1). Per CLI UX council finding: "semantic model/mode incompatibility known to the domain deserves a typed error."
57
+ - `gflow video i2v` CLI: drop `omni-flash` from the i2v command's `--model` Click `Choice` tuple entirely (cleanest UX per CLI UX council). The `--help` output then lists only valid models; users see the constraint at help time. Note: t2v / r2v keep `omni-flash` in their Choice.
58
+ - `gflow video i2v` CLI: when `--model` omitted → resolve to `I2V_DEFAULT_MODEL` (`veo-lite`). When a deserialized config still names `omni-flash` (e.g. from a stale `--config` JSON), the Click callback raises `ModelModeIncompatibilityError`.
59
+ - **Defense-in-depth transport guard** in `_generate_video_locked`: place **immediately after `_select_video_model` (~L1170)** and BEFORE any `_attach_frame` call (Architect + Performance both flagged this as the right placement — fails before any DOM mutation, no cleanup needed, no `page.reload()`). Guard checks `mode is Mode.I2V and (start_image is not None or end_image is not None) and not model.supports_i2v_interpolation()` → raises `ModelModeIncompatibilityError`. Catches direct `FlowApiClient` callers (gflow-cli-remotion) who bypass Click.
60
+ - **Structlog event** `ui_automation_video.model_mode_rejected` emitted by the transport guard before raising — fields `{model, mode, has_start_image, has_end_image, issue_ref: "#125"}`. Required for e2e assertion per CLI UX council + [[verification-ledger-5-layer]].
61
+ - `--model` Click `help=` text on i2v + i2v command `examples=` corrected.
62
+ - Unit tests for the typed error, Choice-drop, default resolution, transport guard, and structlog assertion — see §6.
63
+ - CHANGELOG entries under both `### Fixed` and `### Changed` (the default-model shift is a Changed behaviour worth surfacing separately).
64
+ - Update issue #125 with the actual root cause and link the PR.
65
+ - Ship two diagnostic probes (`capture_i2v_post_bind_state.py`, `capture_i2v_intercept_submit.py`). **DROP probe v1 (`capture_i2v_upload_dialog_dom.py`)** — it proved a refuted hypothesis; ship-as-doc was post-hoc justification per Devil's Advocate.
66
+
67
+ ### Out of scope (deferred — with evidence-based plan)
68
+
69
+ - **r2v + omni-flash compatibility** — Devil's Advocate flagged for in-scope inclusion. Probing r2v requires extending the probe with `--mode references` (different sub-mode, different attach helper `_attach_references`, different endpoint family `batchAsyncGenerateVideoReferenceImages`). Material rewrite. **Decision: file follow-up issue with a one-line probe extension as the first task. Defer scope expansion until evidence in hand.** The plan's transport guard is structured so adding r2v rejection later is a one-line change (`mode is Mode.R2V and not model.supports_r2v(...)`).
70
+ - **omni-flash + start-only i2v** — RESOLVED by probe v5: also routes T2V. Already covered by the in-scope reject-omni-flash-for-any-i2v rule. No longer "unverified strictness."
71
+ - **Full model+mode compatibility matrix** — broader spec; separate work.
72
+ - **Selector-cascade hardening for `_upload_via_open_dialog`** (originally Stage A from the predict review) — no longer needed; probe v1 confirmed the selector works on pt-BR. Drop this scope. (Probe itself dropped from ship list per above.)
73
+
74
+ ## 4. Files touched — council-revised
75
+
76
+ | File | Purpose | Change |
77
+ |---|---|---|
78
+ | `src/gflow_cli/api/video.py` | Domain | Add `VideoModel.supports_i2v_interpolation()` classmethod. Add `I2V_DEFAULT_MODEL = VideoModel.VEO_3_1_LITE`. Per Architect: "domain invariant, not adapter knowledge — analogous to `Aspect.wire()`." |
79
+ | `src/gflow_cli/errors.py` | Typed error | Add `ModelModeIncompatibilityError(GFlowError)` with `exit_code=17`. Per CLI UX council. |
80
+ | `src/gflow_cli/cli_video.py` | CLI surface | Drop `omni-flash` from i2v `--model` Click `Choice` (cleanest discoverability per CLI UX). Add a Click callback resolving omitted `--model` to `I2V_DEFAULT_MODEL`. Raise `ModelModeIncompatibilityError` if a deserialized config still names `omni-flash` for i2v. Update i2v `--model help=` and command examples. |
81
+ | `src/gflow_cli/api/transports/ui_automation_video.py` | Transport guard | In `_generate_video_locked`, **immediately after `_select_video_model` (~L1170), BEFORE `_attach_frame`**: emit `ui_automation_video.model_mode_rejected` event and raise `ModelModeIncompatibilityError` if `mode is Mode.I2V and (start_image is not None or end_image is not None) and not model.supports_i2v_interpolation()`. Per Architect + Performance: earlier placement = no DOM mutation, no cleanup needed. **No `page.reload()`** — drop the R6 mitigation entirely. |
82
+ | `tests/api/test_video.py` (or sibling) | Unit | `test_supports_i2v_interpolation_matrix` parametrized over all 5 VideoModel variants. `test_i2v_default_model_is_veo_lite`. |
83
+ | `tests/errors/test_exit_codes.py` (or sibling) | Unit | `test_model_mode_incompatibility_error_exit_code_17` + ordering-invariant. |
84
+ | `tests/cli/test_cli_video.py` (or sibling) | Unit | i2v --help no longer lists omni-flash; omitted --model resolves to veo-lite; explicit omni-flash via stale config raises exit 17. |
85
+ | `tests/api/transports/test_ui_automation_video.py` (or sibling) | Unit | `test_transport_rejects_i2v_with_omni_flash` — stubbed request DTO, assert raise + `model_mode_rejected` event captured. |
86
+ | `CHANGELOG.md` | Release note | New `### Fixed` entry (i2v silent T2V regression) + new `### Changed` entry (i2v default model shift to veo-lite). |
87
+ | `scripts/dev/capture_i2v_post_bind_state.py` | Dev tooling | NEW — slot-state regression probe. |
88
+ | `scripts/dev/capture_i2v_intercept_submit.py` | Dev tooling | NEW — definitive zero-credit reproducer (the smoking-gun probe). |
89
+ | ~~`scripts/dev/capture_i2v_upload_dialog_dom.py`~~ | ~~Dev tooling~~ | **DROPPED from ship list** — proved a refuted hypothesis; not maintaining as documentation. |
90
+
91
+ ## 5. Implementation steps (in order — each a focused commit) — council-revised
92
+
93
+ 1. **Add `ModelModeIncompatibilityError`** to `gflow_cli.errors` + wire into `EXIT_CODE_MAP` with `exit_code=17`. Unit test for ordering-invariant + the new mapping.
94
+ 2. **Add `VideoModel.supports_i2v_interpolation()` + `I2V_DEFAULT_MODEL`** in `api/video.py` + unit tests.
95
+ 3. **Drop omni-flash from i2v's `--model` Click `Choice`; add resolution callback** in `cli_video.py`. Add `ModelModeIncompatibilityError` raise for the stale-config edge case. Unit tests for both paths.
96
+ 4. **Transport guard** at the correct placement (just after `_select_video_model`) in `_generate_video_locked` + structlog event + unit test stubbing the request DTO. Verify no `page.reload()` is added.
97
+ 5. **Update `--model help=` text + i2v command examples** in `cli_video.py`.
98
+ 6. **CHANGELOG**: `### Fixed` + `### Changed` entries.
99
+ 7. **Add the two dev probes** to `scripts/dev/`: `capture_i2v_post_bind_state.py` + `capture_i2v_intercept_submit.py`. Do NOT add `capture_i2v_upload_dialog_dom.py`.
100
+ 8. **Update issue #125** with the corrected root cause and link to the PR (in §7 verification, after merge).
101
+
102
+ ## 6. Test plan — council-revised
103
+
104
+ ### Unit tests
105
+
106
+ - `test_omni_flash_does_not_support_i2v_interpolation`: `VideoModel.OMNI_FLASH.supports_i2v_interpolation() is False`
107
+ - `test_veo_3_1_models_support_i2v_interpolation`: parametrize across the four VEO_3_1_* variants, all return True
108
+ - `test_i2v_default_model_constant`: `I2V_DEFAULT_MODEL is VideoModel.VEO_3_1_LITE`
109
+ - `test_model_mode_incompatibility_error_exit_code_is_17`: `ModelModeIncompatibilityError().exit_code == 17` and the class is registered in `EXIT_CODE_MAP`
110
+ - `test_exit_code_map_ordering_invariant_still_holds` after the new entry (per [[exit-code-map-ordering-invariant-test-pitfall]])
111
+ - `test_i2v_click_choice_excludes_omni_flash`: introspect the i2v command's `--model` Click `Choice` — `"omni-flash" not in choices`. (Compare to t2v Choice which DOES include it.)
112
+ - `test_i2v_cli_resolves_default_to_veo_lite`: `gflow video i2v start.jpg "p" --end-image end.jpg` (no --model) → resolved model in the request DTO is `VideoModel.VEO_3_1_LITE`
113
+ - `test_i2v_cli_rejects_stale_config_with_omni_flash`: a deserialized config JSON pointing at omni-flash for i2v → exits **17** (not 2) with stderr containing "#125" and "veo-lite"
114
+ - `test_transport_raises_on_i2v_with_omni_flash_and_end_image`: invoke `_generate_video_locked` with a stubbed request `(model=OMNI_FLASH, mode=I2V, start_image=Path, end_image=Path)` → raises `ModelModeIncompatibilityError`, structlog captures `model_mode_rejected` event with fields `{model: "omni_flash", mode: "I2V", has_start_image: True, has_end_image: True, issue_ref: "#125"}`. **No DOM mutation must have occurred** — assert no `_attach_frame` call fired (via mock).
115
+ - `test_transport_raises_on_i2v_with_omni_flash_and_start_only`: same shape but `end_image=None`, `start_image=Path` — still raises (omni-flash rejected for any i2v ref, per probe evidence).
116
+ - `test_transport_does_NOT_raise_on_t2v_with_omni_flash`: pure t2v + omni-flash is a valid combination — guard must NOT fire.
117
+
118
+ ### Integration tests
119
+
120
+ - BDD scenario: "user runs i2v with default model" → command resolves to veo-lite, no Flow interaction. Assert `structlog` shows `model_mode_rejected` is NOT emitted.
121
+ - BDD scenario: "in-process API caller (e.g. flow_workflow.py shape) passes `model=OMNI_FLASH, mode=I2V, start_image=Path` to `FlowApiClient.generate_video`" → raises `ModelModeIncompatibilityError`, exit code 17. **This is the safety net for gflow-cli-remotion-style consumers.**
122
+ - Audit existing i2v integration tests: any fixture using omni-flash for i2v must be updated to a Veo 3.1 model.
123
+
124
+ ### Live e2e (1 paid credit)
125
+
126
+ - Re-run probe v5 (`capture_i2v_intercept_submit.py --model veo-lite ...`) zero-credit sanity check — captured URL must still be `StartAndEndImage` with bound mediaIds.
127
+ - Then a live `gflow video i2v 01-t2i.jpg "<tightened stickman motion prompt>" --end-image 02-i2i.jpg --model veo-lite --aspect 9:16 --profile promo-denon82` → expect:
128
+ - structured log `ui_automation_video.generate_captured` event with `url=batchAsyncGenerateVideoStartAndEndImage` and `image_inputs.startImage` + `image_inputs.endImage` non-null
129
+ - **assert structured log does NOT contain `ui_automation_video.model_mode_rejected`** (positive verification that the new guard didn't false-fire on a valid combination)
130
+ - output mp4 visually: 2D ink line-art stickman starting at desk (matches 01-t2i.jpg), interpolating to arms-raised at sunrise (matches 02-i2i.jpg)
131
+ - 5-layer verification ledger per memory [[verification-ledger-5-layer]]: file count, magic bytes (mp4 signature), Pillow dims (720×1280), structlog invariants (above), user gallery confirmation.
132
+
133
+ ## 7. Verification ladder (definition of done) — council-revised
134
+
135
+ - [ ] `ruff format --check` + `ruff check` clean on `src/gflow_cli/{cli_video,errors,api/video,api/transports/ui_automation_video}.py` and the two dev probe scripts shipping.
136
+ - [ ] `pyright` clean on the same scoped paths.
137
+ - [ ] All new unit tests pass (see §6).
138
+ - [ ] Scoped pytest of `tests/cli/` + `tests/api/` + `tests/api/transports/` + `tests/errors/` passes (full sweep deferred to CI per [[full-test-suite-ooms]]).
139
+ - [ ] BDD/integration tests pass.
140
+ - [ ] **Exit-code-map ordering-invariant test passes** (per [[exit-code-map-ordering-invariant-test-pitfall]]) — adding code 17 must not invert any prior subclass-relation invariant.
141
+ - [ ] Probe v5 re-run with `--model veo-lite` still produces `StartAndEndImage` URL with bound mediaIds (zero credit).
142
+ - [ ] Probe v5 re-run with `--model omni-flash --start-only` still produces T2V (zero credit — proves the rejection is still warranted).
143
+ - [ ] 1 paid live e2e i2v run completes; structured log shows `generate_captured.url=batchAsyncGenerateVideoStartAndEndImage` with non-null mediaIds AND `model_mode_rejected` event is NOT emitted.
144
+ - [ ] User watches the output mp4 and verbally confirms it's a 2D ink line-art stickman desk → sunrise scene matching the refs.
145
+ - [ ] Issue #125 comment thread updated with the actual root cause + closed by PR merge.
146
+ - [ ] CHANGELOG entries present under `[Unreleased]` — both `### Fixed` and `### Changed`.
147
+
148
+ ## 8. Risks + mitigations
149
+
150
+ | Risk | Severity | Mitigation |
151
+ |---|---|---|
152
+ | R1: Changing default model silently surprises users who already had a working incantation | LOW — prior incantation was broken (T2V output); making it work correctly is a strict improvement | None needed beyond clear CHANGELOG note |
153
+ | R2: veo-lite has different cost/quality than omni-flash | LOW — both are tier-one lite models; veo-3.1-lite cost is documented in Flow's UI per `MEDIA_GENERATION_PAYGATE_TIER: PAYGATE_TIER_ONE` | Document in --model help text |
154
+ | R3: omni-flash + start-only i2v might actually work (unverified) | MEDIUM — if it does work, our strict rejection blocks a valid combination | Conservative reject in this PR; reverse with probe evidence in a follow-up if proven |
155
+ | R4: r2v + omni-flash has the same silent-drop pathology | MEDIUM — separate UI surface, separate ticket needed | Out of scope; file follow-up issue with link from #125 |
156
+ | R5: Hidden in-process API callers (scripts using `FlowApiClient` directly like `gflow-cli-remotion/flow_workflow.py`) bypass the CLI validation | MEDIUM | The transport guard in `_generate_video_locked` is the safety net for these callers |
157
+ | ~~R6: pre-submit guard raises but the page is left in a dirty state for the pool~~ | ~~LOW~~ | **DROPPED per Performance council review.** Guard now placed at L1170 (immediately after `_select_video_model`, BEFORE any `_attach_frame`) — fires before any DOM-state mutation, no Page cleanup needed, no `page.reload()`. Architect concurred ("earlier-fail is cleaner than dirty-state cleanup"). |
158
+
159
+ ## 9. Rollback
160
+
161
+ - Revert the PR as a single commit-range. No DB migrations, no settings changes, no state mutations.
162
+ - The transport guard fails-closed: if a user with cached venv hits the guard on a stale config, they get a clear error pointing at #125 with remediation. No silent regression.
163
+
164
+ ## 10. CHANGELOG entries — council-revised (two sections)
165
+
166
+ ```markdown
167
+ ### Fixed
168
+
169
+ - `gflow video i2v` silently routed every call to the T2V endpoint with
170
+ `image_inputs: null` when the model was `omni-flash` (Flow's last-used
171
+ default in most sessions). Flow's frontend rejects omni-flash + frame
172
+ refs and falls back to text-only generation, but the rejection is
173
+ invisible to the client — every i2v paid run on v0.10.0 burned a
174
+ credit for a pure text-to-video generation that ignored the supplied
175
+ start/end frames. Issue #125. Fix: omni-flash dropped from the i2v
176
+ `--model` Click `Choice` entirely; a defense-in-depth transport guard
177
+ in `_generate_video_locked` raises `ModelModeIncompatibilityError`
178
+ (exit code 17) for direct `FlowApiClient` callers that bypass the CLI.
179
+
180
+ ### Changed
181
+
182
+ - `gflow video i2v` default model is now `veo-lite` (was: inherit
183
+ Flow's last-used, which was typically `omni-flash` — see Fixed). The
184
+ veo-3.1 family is the only model line that supports i2v
185
+ interpolation; omni-flash is now correctly rejected for any i2v
186
+ invocation (start-only or start+end). Explicit `--model omni-flash`
187
+ for `gflow video t2v` and `gflow video r2v` remains valid.
188
+ ```
189
+
190
+ ## 11. Migration / backward compat
191
+
192
+ - No breaking config or env-var changes.
193
+ - v0.10.0 users running `gflow video i2v ... --end-image ...` without explicit `--model` previously got silent T2V output; they now get correct interpolation (silent improvement, no surprise).
194
+ - v0.10.0 users running `gflow video i2v ... --end-image ... --model omni-flash` previously got silent T2V; they now get a clear error with `gflow video i2v ... --end-image ... --model veo-lite` as the remediation.
195
+ - BREAKING for: nobody. The prior behavior was a silent bug.
196
+
197
+ ---
198
+
199
+ ## Appendix: probe scripts
200
+
201
+ All zero-credit. Only two ship in this PR per Devil's Advocate review (probe v1 dropped — proved a refuted hypothesis, no future-locale-regression value).
202
+
203
+ | Probe | What it proved | Ships? |
204
+ |---|---|---|
205
+ | `capture_i2v_upload_dialog_dom.py` | "Incluir no comando" pt-BR button matches the production `add_btn` selector — selector cascade is correct (REFUTED original hypothesis). | **NO** — proved a refuted hypothesis; not maintaining as documentation. |
206
+ | `capture_i2v_post_bind_state.py` | `FRAME_SLOTS_STRUCT.count()` transitions 2 → 1 → 0 after binds; submit button is unambiguous (single arrow_forward "Criar" button); slots stay bound after prompt typing. | **YES** — useful future probe for slot-state regressions. |
207
+ | `capture_i2v_intercept_submit.py` | Intercepts the submit XHR via `page.route(..., abort)` and inspects the request body. omni-flash → T2V with null images (both start+end and start-only); veo-lite → StartAndEndImage with populated mediaIds. **This is the definitive reproducer.** | **YES** — definitive regression probe for future model/mode work. |
@@ -8,7 +8,8 @@ Supported tools that auto-discover this file: Cursor, Codex, Aider, Jules, Devin
8
8
 
9
9
  - Unofficial Python CLI for [Google Flow](https://labs.google/fx/tools/flow) — drives Veo (image-to-video, text-to-video) and Imagen (text-to-image) generations from the terminal by reverse-engineering Flow's private REST API at `aisandbox-pa.googleapis.com`.
10
10
  - Python 3.11+ · `uv`-managed · `hatchling` builds · Playwright Chromium transport · `pyright` strict · `ruff` · `pytest`.
11
- - Single-package modular monolith. Top-level modules under `src/gflow_cli/`: `api/`, `auth/`, `browser_manager.py`, `cli.py`, `_cli_helpers.py`, `cli_data.py`, `cli_image.py`, `cli_run.py`, `cli_video.py`, `config.py`, `data/`, `errors.py`, `exceptions.py`, `image_batch.py`, `manifest.py`, `observability.py`, `paths.py`, `profile_store.py`.
11
+ - Single-package modular monolith. Top-level modules under `src/gflow_cli/`: `api/`, `auth/`, `browser_manager.py`, `cli.py`, `_cli_helpers.py`, `cli_character.py`, `cli_data.py`, `cli_image.py`, `cli_models.py`, `cli_run.py`, `cli_scene.py`, `cli_video.py`, `config.py`, `data/`, `errors.py`, `exceptions.py`, `image_batch.py`, `manifest.py`, `observability.py`, `paths.py`, `profile_store.py`.
12
+ - Command surface: `gflow auth`, `gflow image` (t2i/i2i/upload), `gflow video` (t2v/i2v/r2v/batch/chain), `gflow character` (create/list/show/voices — reusable project-scoped Flow Character entities), `gflow scene` (create/show — Add Clip / Scenes, with `create --output` for credit-free server-side extended video), and `gflow data` (catalog queries).
12
13
  - Requires a Google AI Ultra or Pro subscription with Flow access. All generations bill against the user's own Google account.
13
14
 
14
15
  ## Headed-browser dependency (architectural reality)
@@ -28,7 +29,7 @@ If you can help unblock a pure HTTP transport (especially for video generation,
28
29
  - Copy `.env.template` to `.env.local`; never commit `.env.local`. It documents every env var.
29
30
  - Output goes to `./tmp/` for scripts/tests or `$GFLOW_CLI_OUTPUT_DIR` for CLI outputs (defaults to `./out/`).
30
31
  - One-time auth: `gflow auth login --browser chrome`. The `--browser chrome` flag is mandatory; the CLI fails fast on other strategies.
31
- - Use `/gflow:plan` to see the active phase before starting work; `/gflow:known-issues` before touching auth or reCAPTCHA code paths.
32
+ - Use `/gflow:status` to see the current task before starting work; `/gflow:known-issues` before touching auth or reCAPTCHA code paths.
32
33
 
33
34
  ## Testing instructions — The Impeccable Routine
34
35
 
@@ -55,7 +56,7 @@ Or invoke the wrapper: `/gflow:check`.
55
56
 
56
57
  - Type hints everywhere; `pyright` strict on `src/gflow_cli`.
57
58
  - Structured logging only (`structlog`) — **never** raw `print()` or `import logging` in `src/`.
58
- - Errors as RFC 9457 Problem Details with stable per-class exit codes (3–16, where 16 is the `DataStoreError` family from `gflow_cli.data`). See `src/gflow_cli/errors.py::EXIT_CODE_MAP` for the complete mapping.
59
+ - Errors as RFC 9457 Problem Details with stable per-class exit codes (3–21, e.g. 16 is the `DataStoreError` family, 19 `SceneConcatError`, 20 `FrameExtractionError`, 21 `ChainPartialError`). See `src/gflow_cli/errors.py::EXIT_CODE_MAP` for the complete mapping.
59
60
  - 100-char line length, `ruff` configured. Imports sorted by `ruff` (isort rules).
60
61
 
61
62
  ## PR instructions
@@ -66,13 +67,30 @@ Or invoke the wrapper: `/gflow:check`.
66
67
  - Run `/gflow:check` (or the Impeccable Routine) before every commit.
67
68
  - All releases require a signed annotated tag (`git tag -s vX.Y.Z`); CI rejects unsigned tags.
68
69
 
70
+ ## Skills reference (cross-tool)
71
+
72
+ The `skills/` directory ships installable agent skill docs in plain Markdown with YAML frontmatter. Any agent can consume them directly:
73
+
74
+ | Skill | Path | When to load |
75
+ |---|---|---|
76
+ | `gflow-cli` | [`skills/gflow-cli/SKILL.md`](skills/gflow-cli/SKILL.md) | User wants to run any `gflow` command — auth, T2V, I2V, T2I, I2I, batch |
77
+ | `predict` | [`skills/predict/SKILL.md`](skills/predict/SKILL.md) | Pre-implementation adversarial analysis before any high-stakes change |
78
+ | `scenario` | [`skills/scenario/SKILL.md`](skills/scenario/SKILL.md) | Edge-case explorer after a predict GO/CAUTION |
79
+ | `pr-council-review` | [`skills/pr-council-review/SKILL.md`](skills/pr-council-review/SKILL.md) | Multi-dimensional PR council review |
80
+
81
+ **Cursor / Aider / Codex / Gemini CLI:** paste or include the relevant `SKILL.md` in your system context.
82
+ **Claude Code:** symlink `skills/gflow-cli` to `~/.claude/skills/gflow-cli` to register the skill; the `/gflow:` slash commands (in `.claude/commands/gflow/`) are auto-discovered from the project directory.
83
+ **Custom agents:** fetch `skills/gflow-cli/SKILL.md` into your knowledge base before answering gflow questions.
84
+
85
+ The SkillOpt harness at `scripts/dev/skillopt/` measures how accurately each skill guides an agent, and supports multiple providers (Anthropic, OpenAI-compat, Gemini, local models). See [`scripts/dev/skillopt/README.md`](scripts/dev/skillopt/README.md).
86
+
69
87
  ## Where to look next
70
88
 
71
89
  - **Architecture & target shape** → [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md)
72
90
  - **Mandates & routing rules** → [docs/AGENT_GUIDE.md](docs/AGENT_GUIDE.md)
73
91
  - **Full docs index** → [docs/INDEX.md](docs/INDEX.md)
74
92
  - **Known issues** (read before touching auth / reCAPTCHA) → [KNOWN_ISSUES.md](KNOWN_ISSUES.md)
75
- - **Active phase & backlog** → [PLAN.md](PLAN.md) or run `/gflow:plan`
93
+ - **Current task** `/gflow:status` · **Create a feature plan** `/gflow:plan <feature>` · **Full roadmap** → [PLAN.md](PLAN.md)
76
94
  - **Release protocol** → [RELEASE.md](RELEASE.md)
77
95
 
78
96
  ## Claude Code-specific notes