gflow-cli 0.2.0a1__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 (65) hide show
  1. gflow_cli-0.2.0a1/.claude/README.md +58 -0
  2. gflow_cli-0.2.0a1/.claude/commands/release.md +86 -0
  3. gflow_cli-0.2.0a1/.env.template +59 -0
  4. gflow_cli-0.2.0a1/.gitattributes +63 -0
  5. gflow_cli-0.2.0a1/.github/workflows/ci.yml +33 -0
  6. gflow_cli-0.2.0a1/.github/workflows/release.yml +51 -0
  7. gflow_cli-0.2.0a1/.gitignore +53 -0
  8. gflow_cli-0.2.0a1/CHANGELOG.md +59 -0
  9. gflow_cli-0.2.0a1/CLAUDE.md +130 -0
  10. gflow_cli-0.2.0a1/CONTRIBUTING.md +113 -0
  11. gflow_cli-0.2.0a1/DISCLAIMER.md +72 -0
  12. gflow_cli-0.2.0a1/KNOWN_ISSUES.md +143 -0
  13. gflow_cli-0.2.0a1/LICENSE +21 -0
  14. gflow_cli-0.2.0a1/PKG-INFO +404 -0
  15. gflow_cli-0.2.0a1/PLAN.md +336 -0
  16. gflow_cli-0.2.0a1/README.md +351 -0
  17. gflow_cli-0.2.0a1/docs/ARCHITECTURE.md +242 -0
  18. gflow_cli-0.2.0a1/docs/AUTHENTICATION.md +251 -0
  19. gflow_cli-0.2.0a1/docs/CONFIGURATION.md +182 -0
  20. gflow_cli-0.2.0a1/docs/INDEX.md +36 -0
  21. gflow_cli-0.2.0a1/docs/SECURITY.md +125 -0
  22. gflow_cli-0.2.0a1/docs/USAGE.md +262 -0
  23. gflow_cli-0.2.0a1/docs/superpowers/plans/2026-05-09-video-mvp-orchestration.md +387 -0
  24. gflow_cli-0.2.0a1/docs/superpowers/plans/2026-05-09-video-mvp.md +2006 -0
  25. gflow_cli-0.2.0a1/pyproject.toml +78 -0
  26. gflow_cli-0.2.0a1/samples/README.md +57 -0
  27. gflow_cli-0.2.0a1/samples/captured/01_upload_image.json +44 -0
  28. gflow_cli-0.2.0a1/samples/captured/02_batchAsyncGenerateVideoText.json +118 -0
  29. gflow_cli-0.2.0a1/samples/captured/03_batchCheckAsyncVideoGenerationStatus.json +72 -0
  30. gflow_cli-0.2.0a1/samples/captured/04_archive_workflow.json +32 -0
  31. gflow_cli-0.2.0a1/samples/captured/05_createProject.json +32 -0
  32. gflow_cli-0.2.0a1/scripts/smoke_e2e.py +78 -0
  33. gflow_cli-0.2.0a1/skills/README.md +27 -0
  34. gflow_cli-0.2.0a1/skills/gflow-cli/SKILL.md +156 -0
  35. gflow_cli-0.2.0a1/src/flow_cli/__init__.py +3 -0
  36. gflow_cli-0.2.0a1/src/flow_cli/__main__.py +6 -0
  37. gflow_cli-0.2.0a1/src/flow_cli/api/__init__.py +18 -0
  38. gflow_cli-0.2.0a1/src/flow_cli/api/client.py +246 -0
  39. gflow_cli-0.2.0a1/src/flow_cli/api/dto.py +137 -0
  40. gflow_cli-0.2.0a1/src/flow_cli/api/recaptcha.py +107 -0
  41. gflow_cli-0.2.0a1/src/flow_cli/api/routes.py +37 -0
  42. gflow_cli-0.2.0a1/src/flow_cli/api/video.py +112 -0
  43. gflow_cli-0.2.0a1/src/flow_cli/auth.py +87 -0
  44. gflow_cli-0.2.0a1/src/flow_cli/cli.py +184 -0
  45. gflow_cli-0.2.0a1/src/flow_cli/cli_video.py +322 -0
  46. gflow_cli-0.2.0a1/src/flow_cli/config.py +116 -0
  47. gflow_cli-0.2.0a1/src/flow_cli/manifest.py +58 -0
  48. gflow_cli-0.2.0a1/src/flow_cli/paths.py +82 -0
  49. gflow_cli-0.2.0a1/src/flow_cli/profile_store.py +226 -0
  50. gflow_cli-0.2.0a1/tests/__init__.py +0 -0
  51. gflow_cli-0.2.0a1/tests/api/__init__.py +0 -0
  52. gflow_cli-0.2.0a1/tests/api/test_client.py +44 -0
  53. gflow_cli-0.2.0a1/tests/api/test_client_generate_video.py +77 -0
  54. gflow_cli-0.2.0a1/tests/api/test_dto.py +91 -0
  55. gflow_cli-0.2.0a1/tests/api/test_recaptcha.py +58 -0
  56. gflow_cli-0.2.0a1/tests/api/test_routes.py +36 -0
  57. gflow_cli-0.2.0a1/tests/api/test_video.py +83 -0
  58. gflow_cli-0.2.0a1/tests/test_auth.py +52 -0
  59. gflow_cli-0.2.0a1/tests/test_cli_video.py +150 -0
  60. gflow_cli-0.2.0a1/tests/test_config.py +104 -0
  61. gflow_cli-0.2.0a1/tests/test_manifest.py +56 -0
  62. gflow_cli-0.2.0a1/tests/test_paths.py +51 -0
  63. gflow_cli-0.2.0a1/tests/test_profile_store.py +157 -0
  64. gflow_cli-0.2.0a1/tests/test_smoke.py +28 -0
  65. gflow_cli-0.2.0a1/uv.lock +732 -0
@@ -0,0 +1,58 @@
1
+ # `.claude/` — repo-local Claude Code surface
2
+
3
+ This directory holds **internal maintainer workflows** that are bundled with the repo so any contributor running Claude Code in this checkout gets the same environment.
4
+
5
+ > Distinct from `skills/flow-cli/SKILL.md` at the repo root, which is the **published** Skill end users install into their own Claude Code to learn how to use `gflow` from agent contexts. `.claude/` is for *us*, the maintainers; `skills/` is for *them*, the users.
6
+
7
+ ## Layout
8
+
9
+ ```
10
+ .claude/
11
+ ├── README.md ← this file
12
+ └── commands/ ← repo-local slash commands
13
+ └── release.md ← `/release` — automates the version-bump + tag + push flow
14
+ ```
15
+
16
+ Optional additions when needed:
17
+
18
+ ```
19
+ .claude/
20
+ ├── settings.json ← Claude Code settings (NOT committed if user-specific)
21
+ ├── hooks/ ← repo-local PreToolUse / PostToolUse / Stop hooks
22
+ └── skills/ ← internal maintainer skills (not for end users)
23
+ └── <name>/SKILL.md
24
+ ```
25
+
26
+ ## Adding a slash command
27
+
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.
29
+
30
+ Example: `commands/foo.md` → invoked as `/foo`.
31
+
32
+ ## Adding an internal skill
33
+
34
+ Same shape as the published one in `skills/flow-cli/`:
35
+
36
+ ```markdown
37
+ ---
38
+ name: my-skill
39
+ description: When to invoke this skill (1-2 sentences).
40
+ ---
41
+
42
+ # Body of the skill — how to do the thing.
43
+ ```
44
+
45
+ Drop into `.claude/skills/<name>/SKILL.md`.
46
+
47
+ ## Settings
48
+
49
+ `settings.json` is intentionally not committed by default — permissions and tool allowlists are usually a per-developer preference. If we ever agree on a project-wide set (e.g. always allow `uv run pytest` without a prompt), commit it then.
50
+
51
+ ## Hooks
52
+
53
+ Same caveat as settings — repo-local hooks override user hooks and can surprise contributors. Only commit a hook when there's a strong, project-wide reason (e.g. block commits that would expose secrets).
54
+
55
+ ## See also
56
+
57
+ - [CLAUDE.md](../CLAUDE.md) — project memory hub for any AI agent.
58
+ - [docs/INDEX.md](../docs/INDEX.md) — full documentation index.
@@ -0,0 +1,86 @@
1
+ ---
2
+ description: Cut a new flow-cli release — bump version, update CHANGELOG, tag, push.
3
+ ---
4
+
5
+ # `/release` — Cut a new flow-cli release
6
+
7
+ You are about to release a new version of `flow-cli`. Follow this sequence verbatim — every step matters.
8
+
9
+ ## Inputs
10
+
11
+ Ask the user (if not already provided):
12
+ 1. **Version** — the new SemVer (e.g. `0.2.0`, `0.2.0a1`, `1.0.0-rc1`). If they don't know, look at the latest entry in `CHANGELOG.md` `[Unreleased]` and propose the next bump (PATCH for fixes only, MINOR for new features, MAJOR for breaks).
13
+ 2. **Pre-release?** — `0.x.y` is alpha by definition. Only the user can say if a `0.x.y-rc1` should ship.
14
+
15
+ ## Sequence
16
+
17
+ 1. **Verify clean working tree.**
18
+ ```bash
19
+ git status --short
20
+ ```
21
+ Must be empty. If not, abort and tell the user to commit/stash first.
22
+
23
+ 2. **Verify on `main`, up-to-date with `origin/main`.**
24
+ ```bash
25
+ git rev-parse --abbrev-ref HEAD # must be "main"
26
+ git fetch origin
27
+ git rev-list HEAD..origin/main # must be empty
28
+ ```
29
+
30
+ 3. **Run quality gates.** Reject if any fail.
31
+ ```bash
32
+ uv run ruff check src tests
33
+ uv run ruff format --check src tests
34
+ uv run pyright src
35
+ uv run pytest -q --cov=flow_cli --cov-fail-under=80
36
+ ```
37
+
38
+ 4. **Bump version** in `pyproject.toml`:
39
+ ```toml
40
+ [project]
41
+ version = "<NEW_VERSION>"
42
+ ```
43
+
44
+ 5. **Update `CHANGELOG.md`:**
45
+ - Move all entries under `## [Unreleased]` to a new `## [<NEW_VERSION>] — YYYY-MM-DD` section.
46
+ - Leave `## [Unreleased]` empty.
47
+ - Update the link footer:
48
+ ```
49
+ [Unreleased]: https://github.com/ffroliva/gflow-cli/compare/v<NEW_VERSION>...HEAD
50
+ [<NEW_VERSION>]: https://github.com/ffroliva/gflow-cli/releases/tag/v<NEW_VERSION>
51
+ ```
52
+
53
+ 6. **Commit the release prep.**
54
+ ```bash
55
+ git add pyproject.toml CHANGELOG.md
56
+ git commit -m "release: v<NEW_VERSION>"
57
+ ```
58
+
59
+ 7. **Tag.** Pre-release tags include `-rc*` / `-alpha*` / `-beta*`:
60
+ ```bash
61
+ git tag -a v<NEW_VERSION> -m "v<NEW_VERSION>"
62
+ ```
63
+
64
+ 8. **Push commit + tag.**
65
+ ```bash
66
+ git push origin main
67
+ git push origin v<NEW_VERSION>
68
+ ```
69
+
70
+ 9. **Report.** Tell the user:
71
+ - The pushed tag triggers `.github/workflows/release.yml`.
72
+ - Watch <https://github.com/ffroliva/gflow-cli/actions> for the release workflow.
73
+ - On success: PyPI publish + GitHub Release with auto-generated notes.
74
+ - On failure (most common: PyPI Trusted Publishing not yet configured), point them to <https://pypi.org/manage/account/publishing/>.
75
+
76
+ ## Critical reminders
77
+
78
+ - **NEVER** add `Co-Authored-By: Claude` (or any AI co-author) to the release commit.
79
+ - **NEVER** force-push a release tag once it's been created on GitHub. If a release ships broken, bump to the next PATCH and ship a fix; never rewrite tag history.
80
+ - **NEVER** `--no-verify` your way past hooks. If a hook complains, fix the underlying issue.
81
+ - If quality gates fail at step 3, **STOP**. Do not proceed. Surface the failures to the user.
82
+
83
+ ## See also
84
+
85
+ - [README § Releases](../../README.md#releases) — full release policy & cadence
86
+ - [PLAN § Phase 5](../../PLAN.md#phase-5--public-alpha-release) — first-release exit criteria
@@ -0,0 +1,59 @@
1
+ # flow-cli — example environment variables.
2
+ # Copy to `.env` (in this repo or in $FLOW_CLI_HOME) and customise.
3
+ # All variables are OPTIONAL — defaults work out of the box for most users.
4
+
5
+ # -----------------------------------------------------------------------------
6
+ # Auth & profiles
7
+ # -----------------------------------------------------------------------------
8
+
9
+ # Root directory for Playwright persistent contexts (signed-in Google sessions).
10
+ # Default: %USERPROFILE%/.flow-cli (Windows)
11
+ # ~/.flow-cli (macOS / Linux)
12
+ # FLOW_CLI_HOME=
13
+
14
+ # Default profile name. Override per-call with `--profile <name>`.
15
+ FLOW_CLI_PROFILE=default
16
+
17
+ # -----------------------------------------------------------------------------
18
+ # Output paths
19
+ # -----------------------------------------------------------------------------
20
+
21
+ # Where downloaded assets land. Subfolders are created per kind/date:
22
+ # <output_dir>/images/<YYYY-MM-DD>/<job_id>_<index>.png
23
+ # <output_dir>/videos/<YYYY-MM-DD>/<job_id>.mp4
24
+ #
25
+ # Default (via `platformdirs`):
26
+ # Windows: %USERPROFILE%\Downloads\flow-cli
27
+ # macOS: ~/Downloads/flow-cli
28
+ # Linux: $XDG_DOWNLOAD_DIR/flow-cli (falls back to ~/Downloads/flow-cli)
29
+ # FLOW_CLI_OUTPUT_DIR=
30
+
31
+ # -----------------------------------------------------------------------------
32
+ # Provider selection
33
+ # -----------------------------------------------------------------------------
34
+
35
+ # Backend to use for generations.
36
+ # flow - reverse-engineered Flow REST API (default, requires Ultra/Pro)
37
+ # official - official Veo SDK (planned for v0.3+, requires Gemini API key)
38
+ FLOW_CLI_PROVIDER=flow
39
+
40
+ # Gemini API key — only required when FLOW_CLI_PROVIDER=official.
41
+ # Get one at https://aistudio.google.com/apikey
42
+ # FLOW_CLI_GEMINI_API_KEY=
43
+
44
+ # -----------------------------------------------------------------------------
45
+ # Runtime tuning
46
+ # -----------------------------------------------------------------------------
47
+
48
+ # Per-request HTTP timeout (seconds). Veo videos can take 60-180s each.
49
+ FLOW_CLI_TIMEOUT_SECONDS=600
50
+
51
+ # Logging level — DEBUG | INFO | WARNING | ERROR
52
+ FLOW_CLI_LOG_LEVEL=INFO
53
+
54
+ # Log format — auto | text | json
55
+ # auto = text on TTY, json when piped (default)
56
+ FLOW_CLI_LOG_FORMAT=auto
57
+
58
+ # Concurrency for batch operations (requires multiple profiles, v0.4+).
59
+ FLOW_CLI_CONCURRENCY=1
@@ -0,0 +1,63 @@
1
+ # Normalise line endings to LF in the repository (working tree gets LF too).
2
+ # Cross-platform contributors don't need to worry about CRLF/LF — the repo
3
+ # is the source of truth, and Git enforces LF on add/commit.
4
+
5
+ # Default: detect text vs binary, force LF on text.
6
+ * text=auto eol=lf
7
+
8
+ # Code
9
+ *.py text eol=lf
10
+ *.toml text eol=lf
11
+ *.json text eol=lf
12
+ *.yml text eol=lf
13
+ *.yaml text eol=lf
14
+ *.lock text eol=lf
15
+ *.txt text eol=lf
16
+ *.cfg text eol=lf
17
+ *.ini text eol=lf
18
+
19
+ # Docs / config
20
+ *.md text eol=lf
21
+ *.template text eol=lf
22
+ *.example text eol=lf
23
+ .gitignore text eol=lf
24
+ .gitattributes text eol=lf
25
+ LICENSE text eol=lf
26
+
27
+ # Shell scripts
28
+ *.sh text eol=lf
29
+ *.bash text eol=lf
30
+
31
+ # Windows scripts MUST stay CRLF or they break under PowerShell / cmd.exe
32
+ *.ps1 text eol=crlf
33
+ *.bat text eol=crlf
34
+ *.cmd text eol=crlf
35
+
36
+ # Binary — never touch
37
+ *.png binary
38
+ *.jpg binary
39
+ *.jpeg binary
40
+ *.gif binary
41
+ *.webp binary
42
+ *.ico binary
43
+ *.mp4 binary
44
+ *.mov binary
45
+ *.webm binary
46
+ *.mp3 binary
47
+ *.wav binary
48
+ *.flac binary
49
+ *.zip binary
50
+ *.tar binary
51
+ *.gz binary
52
+ *.bz2 binary
53
+ *.7z binary
54
+ *.pdf binary
55
+ *.woff binary
56
+ *.woff2 binary
57
+ *.ttf binary
58
+ *.otf binary
59
+ *.eot binary
60
+ *.so binary
61
+ *.dll binary
62
+ *.dylib binary
63
+ *.exe binary
@@ -0,0 +1,33 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+
8
+ jobs:
9
+ test:
10
+ runs-on: ubuntu-latest
11
+ strategy:
12
+ matrix:
13
+ python-version: ["3.11", "3.12"]
14
+ steps:
15
+ - uses: actions/checkout@v4
16
+
17
+ - name: Install uv
18
+ uses: astral-sh/setup-uv@v3
19
+
20
+ - name: Set up Python
21
+ run: uv python install ${{ matrix.python-version }}
22
+
23
+ - name: Install deps
24
+ run: uv sync --extra dev
25
+
26
+ - name: Lint
27
+ run: uv run ruff check src tests
28
+
29
+ - name: Type check
30
+ run: uv run pyright src
31
+
32
+ - name: Test (smoke only)
33
+ run: uv run pytest -q
@@ -0,0 +1,51 @@
1
+ name: Release
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "v*.*.*"
7
+
8
+ permissions:
9
+ contents: write # for creating GitHub Releases
10
+ id-token: write # for PyPI Trusted Publishing (OIDC)
11
+
12
+ jobs:
13
+ build-and-publish:
14
+ runs-on: ubuntu-latest
15
+ environment:
16
+ name: pypi
17
+ url: https://pypi.org/p/gflow-cli
18
+ steps:
19
+ - uses: actions/checkout@v4
20
+ with:
21
+ fetch-depth: 0
22
+
23
+ - name: Install uv
24
+ uses: astral-sh/setup-uv@v3
25
+
26
+ - name: Set up Python
27
+ run: uv python install 3.12
28
+
29
+ - name: Verify tag matches pyproject version
30
+ run: |
31
+ TAG=${GITHUB_REF_NAME#v}
32
+ PROJ_VERSION=$(grep -E '^version = ' pyproject.toml | head -1 | cut -d'"' -f2)
33
+ if [ "$TAG" != "$PROJ_VERSION" ]; then
34
+ echo "::error::Tag ($TAG) does not match pyproject.toml version ($PROJ_VERSION)"
35
+ exit 1
36
+ fi
37
+
38
+ - name: Build
39
+ run: uv build
40
+
41
+ - name: Publish to PyPI
42
+ uses: pypa/gh-action-pypi-publish@release/v1
43
+ # No api-token needed — uses OIDC Trusted Publishing.
44
+ # Configure once at https://pypi.org/manage/account/publishing/
45
+
46
+ - name: Create GitHub Release
47
+ uses: softprops/action-gh-release@v2
48
+ with:
49
+ generate_release_notes: true
50
+ files: dist/*
51
+ prerelease: ${{ contains(github.ref_name, '-') }}
@@ -0,0 +1,53 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.egg-info/
6
+ .eggs/
7
+ dist/
8
+ build/
9
+ .venv/
10
+ venv/
11
+ env/
12
+
13
+ # uv
14
+ .uv-cache/
15
+
16
+ # Test / coverage
17
+ .pytest_cache/
18
+ .coverage
19
+ .coverage.*
20
+ htmlcov/
21
+ .tox/
22
+ .mypy_cache/
23
+ .ruff_cache/
24
+ .pyright/
25
+
26
+ # Editors
27
+ .vscode/
28
+ .idea/
29
+ *.swp
30
+ .DS_Store
31
+
32
+ # Project-specific — secrets / session storage (NEVER commit)
33
+ auth/ # any project-local auth dir
34
+ profile_*/ # Chromium persistent contexts (any name)
35
+ *.cookies.json # exported cookie jars
36
+ storage_state.json # Playwright storage_state output
37
+ secrets.json # generic secrets file
38
+ .env # local env overrides (the .env.template IS committed)
39
+ .env.local
40
+ .env.*.local
41
+
42
+ # Generated outputs
43
+ out/
44
+ tmp/
45
+ *.mp4
46
+ *.png
47
+ !docs/**/*.png # docs images are OK
48
+ !tests/fixtures/**/*.png
49
+ samples/*.captured.json # sandbox-recorded API exchanges may contain PII
50
+
51
+ # Claude Code worktrees and lock files
52
+ .claude/worktrees/
53
+ .claude/scheduled_tasks.lock
@@ -0,0 +1,59 @@
1
+ # Changelog
2
+
3
+ All notable changes to `flow-cli` will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ## [0.2.0a1] — 2026-05-09
11
+
12
+ ### Added
13
+ - **`gflow video t2v`** — generate a video from a text prompt via Veo 3.1.
14
+ Flags: `--aspect 9:16|16:9|1:1`, `--seed`, `--output`, `--profile`, `--poll-interval`.
15
+ - **`gflow video i2v`** — generate a video from a start image + text prompt (Veo 3.1 I2V).
16
+ - **`gflow video batch`** — run a TSV manifest of video generations against one shared project.
17
+ - `flow_cli.api` package — low-level REST client (`FlowApiClient`) + value objects
18
+ (`GenerateVideoRequest`, `VideoOperation`, `VideoStatus`) for video generation.
19
+ - `flow_cli.api.recaptcha` — reCAPTCHA Enterprise token minting via Playwright `page.evaluate`.
20
+ `TokenMinter` caches the discovered site key per session; `mint(action)` is called immediately
21
+ before each generation request.
22
+ - `flow_cli.manifest` — TSV manifest parser for `gflow video batch`. Supports optional
23
+ `start_image`, `end_image`, `aspect`, `output_path` columns; skips `# `-prefixed comments.
24
+ - `FLOW_CLI_HEADLESS` env var (`bool`, default `true`). Set to `false` if reCAPTCHA refuses
25
+ to mint tokens in headless mode (Google bot detection fallback).
26
+ - `scripts/smoke_e2e.py` — one-shot live T2V smoke test; run after `gflow auth login` to
27
+ verify the full happy path (create project → generate_video → poll → download).
28
+ - **`CLAUDE.md`** at repo root — project memory hub for AI coding agents
29
+ (Claude Code reads natively; Cursor/Codex/Gemini/Aider can read as reference).
30
+ - **`.claude/`** directory — repo-local Claude Code surface for maintainers.
31
+ - `.claude/README.md` — what goes here, how to extend.
32
+ - `.claude/commands/release.md` — `/release` slash command that automates
33
+ version bump + CHANGELOG migration + tag + push, with quality gates.
34
+ - `flow_cli.profile_store` — profile inventory + default-profile persistence
35
+ in `$FLOW_CLI_HOME/config.toml`. Five-step resolution chain (CLI flag > env >
36
+ config > auto-select > raise) with named exceptions
37
+ (`NoProfilesError`, `NoDefaultProfileError`).
38
+ - New auth subcommands: bare `gflow auth`, `gflow auth list`, `gflow auth use <name>`,
39
+ `gflow auth logout [--profile NAME] [-y]`. First login auto-sets default profile.
40
+ - `KNOWN_ISSUES.md` at repo root — open/mitigated/resolved issues with workarounds.
41
+ - `docs/` tree (INDEX, AUTHENTICATION, CONFIGURATION, ARCHITECTURE, USAGE, SECURITY).
42
+ - `.env.template` documenting every supported env var.
43
+ - GitHub Actions CI: ruff, pyright, pytest on Python 3.11 and 3.12.
44
+ - GitHub Actions release workflow: tag-triggered PyPI publish via Trusted Publishing.
45
+ - MIT license, comprehensive README, [`DISCLAIMER.md`](DISCLAIMER.md), [`CONTRIBUTING.md`](CONTRIBUTING.md).
46
+ - [`skills/flow-cli/SKILL.md`](skills/flow-cli/SKILL.md) — installable Claude Code Skill.
47
+
48
+ ### Removed
49
+ - `flow_cli.providers.FlowProvider` and `flow_cli.models` — superseded by `flow_cli.api`.
50
+ - Legacy CLI stubs: `gflow upload`, `gflow generate`, `gflow status`, `gflow download`,
51
+ `gflow i2v`. Replaced by the wired `gflow video` subgroup.
52
+
53
+ ## [0.1.0] — _unreleased_
54
+
55
+ First skeleton. Not functional end-to-end yet.
56
+
57
+ [Unreleased]: https://github.com/ffroliva/gflow-cli/compare/v0.2.0a1...HEAD
58
+ [0.2.0a1]: https://github.com/ffroliva/gflow-cli/releases/tag/v0.2.0a1
59
+ [0.1.0]: https://github.com/ffroliva/gflow-cli/releases/tag/v0.1.0
@@ -0,0 +1,130 @@
1
+ # CLAUDE.md
2
+
3
+ > **Project memory hub for AI coding agents.** Claude Code reads this natively. Other agents (Cursor, Codex, Gemini CLI, Aider) should read this as a top-level reference.
4
+
5
+ ## What this project is
6
+
7
+ `flow-cli` is an unofficial Python CLI that drives [Google Flow](https://labs.google/fx/tools/flow) (Veo image-to-video, Imagen text-to-image) from the terminal by reverse-engineering Flow's private REST API at `aisandbox-pa.googleapis.com`. Built for Google AI Ultra/Pro subscribers who want to spend their Flow credits via batch automation rather than the web UI.
8
+
9
+ **Same pattern as `edge-tts`:** a community SDK over a private cloud API.
10
+
11
+ ## On every session start
12
+
13
+ 1. Read **[docs/INDEX.md](docs/INDEX.md)** — routing layer for all project docs.
14
+ 2. Read **[PLAN.md](PLAN.md)** — current phase, next concrete tasks, ADRs.
15
+ 3. Read **[KNOWN_ISSUES.md](KNOWN_ISSUES.md)** — open issues to avoid re-discovering.
16
+ 4. Check **[CHANGELOG.md](CHANGELOG.md) `[Unreleased]`** — what's recently shipped.
17
+
18
+ ## Active phase
19
+
20
+ **Phase 1 — Foundation** (refactor scaffold into layered structure, wire `pydantic-settings`, `structlog`, command/query bus). See [PLAN § Phase 1](PLAN.md#phase-1--foundation-target-12-days). Subset already landed: profile-store + `gflow auth` UX (commit `d821f39`).
21
+
22
+ ## Architecture (skim)
23
+
24
+ Layered Clean / Hexagonal — see **[docs/ARCHITECTURE.md](docs/ARCHITECTURE.md)** for the full diagram and rationale.
25
+
26
+ ```text
27
+ interfaces/ → application/ → domain/ ← infrastructure/
28
+ CLI commands / pure FlowProvider,
29
+ queries / business Playwright,
30
+ handlers / logic filesystem
31
+ ports
32
+ ```
33
+
34
+ Dependency rule: **`domain/` depends on nothing**. `application/` depends on `domain/` + ports (Protocols). `infrastructure/` implements the ports. `interfaces/` wires it together.
35
+
36
+ ## CRITICAL rules — invariant, never violate
37
+
38
+ - **Never commit secrets.** `.gitignore` excludes `auth/`, `profile_*/`, `*.cookies.json`, `storage_state.json`, `secrets.json`, `.env`, `.env.local`, `.env.*.local`. If you see one of these staged, abort and tell the user.
39
+ - **Never add `Co-Authored-By: Claude` (or any AI co-author) to commit messages.** Author attribution is the human user's only.
40
+ - **Sessions belong outside the repo.** Default location is `$LOCALAPPDATA/flow-cli/profile_*` (Windows) or `~/.local/share/flow-cli/profile_*` (POSIX) via [`platformdirs`](https://github.com/platformdirs/platformdirs). Never store sessions in `/tmp`, `%TEMP%`, or anywhere the OS auto-reaps.
41
+ - **No `print()` in `src/`** — use `structlog` (or `logging` until structlog lands in Phase 1).
42
+ - **Domain layer is pure** — `src/flow_cli/domain/*` must not import `application/`, `infrastructure/`, or `interfaces/`. No I/O, no frameworks.
43
+ - **Frozen dataclasses for value objects.** Aggregates may have controlled mutation methods, but VOs (AspectRatio, Prompt, JobId, ...) are immutable.
44
+ - **Async all the way down.** Handlers and providers are `async def`. CLI is the only place that calls `asyncio.run(...)`.
45
+ - **TDD is non-negotiable.** Red → Green → Refactor → Commit. Coverage floor: **80% overall**, **90% on `domain/` and `application/`**. See [CONTRIBUTING.md](CONTRIBUTING.md).
46
+
47
+ ## Coding conventions
48
+
49
+ - **Python 3.11+**, strict typing (`pyright --strict` on `src/flow_cli/`), `from __future__ import annotations` at the top of every module.
50
+ - **`@dataclass(frozen=True)`** for value objects and DTOs. `Protocol` for ports.
51
+ - **`pathlib.Path`** everywhere — never raw strings for filesystem paths.
52
+ - **Click + Rich** for the CLI, **httpx + Playwright** for I/O, **pytest + pytest-bdd** for tests.
53
+ - **Conventional Commits** for messages (`feat:`, `fix:`, `docs:`, `test:`, `chore:`, `refactor:`, etc.). See examples in `git log`.
54
+ - **Short files, single responsibility.** ~200-400 lines typical, 800 max. Split into `package/<topic>.py` if growing.
55
+
56
+ ## How to verify your work
57
+
58
+ Run all four BEFORE asking to commit:
59
+
60
+ ```bash
61
+ uv run ruff check src tests # lint
62
+ uv run ruff format --check src tests # formatting
63
+ uv run pyright src # types
64
+ uv run pytest -q --cov=flow_cli # tests + coverage
65
+ ```
66
+
67
+ CI runs the same four on every push (see `.github/workflows/ci.yml`).
68
+
69
+ ## Where to look
70
+
71
+ | I need to… | Read this |
72
+ |---|---|
73
+ | Understand the architecture | [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) |
74
+ | Add a CLI command | [docs/USAGE.md](docs/USAGE.md) + existing patterns in `src/flow_cli/cli.py` |
75
+ | Add a Provider route | [PLAN.md § 4 Feature specs](PLAN.md#4-feature-specs) + existing stubs in `src/flow_cli/providers/flow.py` + capture data in `samples/captured_requests.json` |
76
+ | Touch auth | [docs/AUTHENTICATION.md](docs/AUTHENTICATION.md) |
77
+ | Add a config knob | [docs/CONFIGURATION.md](docs/CONFIGURATION.md) + `.env.template` + (later) `src/flow_cli/shared/config.py` |
78
+ | Write a test | [CONTRIBUTING.md § TDD](CONTRIBUTING.md#test-driven-development-mandatory) + existing patterns in `tests/` |
79
+ | Cut a release | [README § Releases](README.md#releases) — bump version in `pyproject.toml`, update CHANGELOG, `git tag vX.Y.Z`, push |
80
+ | Track a known issue | [KNOWN_ISSUES.md](KNOWN_ISSUES.md) |
81
+ | Understand security posture | [docs/SECURITY.md](docs/SECURITY.md) |
82
+
83
+ ## Common tasks
84
+
85
+ ### Run the CLI from source
86
+
87
+ ```bash
88
+ uv sync
89
+ uv run gflow --help
90
+ uv run gflow auth # bare command — list profiles or login
91
+ uv run gflow auth login --profile experiments # named profile
92
+ ```
93
+
94
+ ### Add a new test (TDD)
95
+
96
+ 1. Write the failing test in `tests/<area>/test_<thing>.py`.
97
+ 2. `uv run pytest tests/<area>/test_<thing>.py` — verify it fails for the right reason.
98
+ 3. Implement the minimum production code to pass.
99
+ 4. Refactor.
100
+ 5. `uv run pytest -q --cov=flow_cli` — verify nothing else broke and coverage didn't regress.
101
+
102
+ ### Update a doc
103
+
104
+ 1. Edit the file under `docs/`.
105
+ 2. Add a row to `docs/INDEX.md` if it's a new file.
106
+ 3. Update `CHANGELOG.md` `[Unreleased]` only if the change is user-visible.
107
+
108
+ ## Things NOT to do
109
+
110
+ - Don't add a feature without a PLAN entry (or update PLAN if scope shifts).
111
+ - Don't `pip install` — always `uv add` so the lockfile stays in sync.
112
+ - Don't put new files in the repo root unless they're truly top-level (LICENSE, README, PLAN, CHANGELOG, etc.). Code goes in `src/`, tests in `tests/`, docs in `docs/`.
113
+ - Don't introduce a new dependency without listing the rationale in PLAN's Decision Log.
114
+ - Don't `--no-verify` your way past a hook. Fix the hook's complaint instead.
115
+ - Don't generate placeholder content (lorem ipsum, "todo: implement"). Either skip the file or write the real thing.
116
+
117
+ ## Reasoning style for an agent
118
+
119
+ - **Verify before claiming done.** Run the quality gates and read the output. "Tests pass" without evidence is not acceptable.
120
+ - **Small, atomic commits.** Each commit message captures one logical change.
121
+ - **Question scope creep.** If the user asks for X and you're tempted to also fix Y, ask first.
122
+ - **Plan before implementing** for anything > 1 file or > 50 LoC. Write the plan into PLAN.md or a comment, then execute.
123
+ - **Show your work.** When you change something non-obvious, leave a one-line comment with the WHY (not the WHAT — the diff already shows the what).
124
+
125
+ ## See also
126
+
127
+ - [README.md](README.md) — public-facing project overview
128
+ - [docs/INDEX.md](docs/INDEX.md) — full doc routing
129
+ - [PLAN.md](PLAN.md) — implementation roadmap with phases & ADRs
130
+ - [.claude/README.md](.claude/README.md) — what's in `.claude/` and how to extend it