Skip to main content
Yanked

This release has been yanked by its maintainers, and will be ignored by installers, except when explicitly specified.
Consider using release 1.0.2 instead.
Reason given by maintainers: Updated Readme

gitaiflow

Python PyPI Downloads Build License GitHub Release GitHub Stars

Maintained by: DjangoPlay icon DjangoPlay


Generate an AI change summary from your git diff -- as a single, timestamped JSON file that's ready to use as a commit title/body, pipe into a commit-msg hook, or feed to another tool/agent.

Works with any AI provider: a free Google Gemini API key, a fully local Ollama model, or any OpenAI-compatible endpoint (OpenAI, Groq, DeepSeek, OpenRouter, vLLM, LM Studio, ...). One config, one output format, no vendor lock-in.

$ gitaiflow --path mailer/ --print-commit

mailer: add retry backoff for failed sends

- Added exponential backoff retry logic in retry.py
- tasks.py now retries send_mail up to 3 times on failure
- No changes to public function signatures

Install

pip install gitaiflow

Configure an AI provider (required)

gitaiflow needs an AI model configured -- it will not run without one.

OpenRouter (recommended)

gitaiflow can use OpenRouter's free model router by default, or any specific free or paid model available through your OpenRouter account.

Create an OpenRouter account and generate an API key:

https://openrouter.ai/

Then add your key to .gitaiflow.env in your repository root:

AI_PROVIDER=custom
AI_BASE_URL=https://openrouter.ai/api/v1
AI_API_KEY=<your-openrouter-api-key>
AI_MODEL=openrouter/free

AI_TEMPERATURE=0.2
AI_MAX_TOKENS=10000
AI_REQUEST_TIMEOUT=60

Keep your API key private. Do not commit .gitaiflow.env or your API key to source control.

openrouter/free automatically selects an available free model, so you do not need to maintain a model name manually.

Use a paid OpenRouter model

If you have access to paid models through OpenRouter, use your own OpenRouter API key and specify the model you want:

AI_API_KEY=<your-openrouter-api-key>
AI_MODEL=<openrouter-model-id>

Usage is charged according to your OpenRouter account and selected model. gitaiflow does not provide or manage the model subscription.

Finding a free OpenRouter model

If you're using OpenRouter and want to pick a specific model rather than the openrouter/free auto-router, list what's currently available instead of hand-writing curl/jq:

gitaiflow --list-models --free-only
ID                                    CONTEXT    FREE
nvidia/nemotron-3.5-lightning:free    128000     yes
meta-llama/llama-3.3-70b:free         131000     yes
...

Drop the --free-only flag to see paid models too, or add --json for the raw OpenRouter response (all metadata fields, not just the table columns shown above). This queries OpenRouter's live catalog on every call -- gitaiflow doesn't maintain its own model list, so newly added or removed models show up automatically.

--list-models works independent of your configured AI_PROVIDER -- it always targets OpenRouter regardless of what you have AI_MODEL set to today, and doesn't require an API key (OpenRouter's catalog endpoint is public). It only looks up models; it never changes your configured AI_MODEL.

Other providers

1. Gemini (free tier, cloud)

export AI_PROVIDER=gemini
export AI_API_KEY=<your-key>          # https://aistudio.google.com/apikey

2. Ollama (local, no API key, no cost)

export AI_PROVIDER=ollama
export AI_MODEL=llama3.2:3b           # must match `ollama list` exactly

3. Any OpenAI-compatible provider (OpenAI, Groq, self-hosted, ...)

export AI_PROVIDER=custom
export AI_BASE_URL=<endpoint>
export AI_API_KEY=<key>
export AI_MODEL=<model>

Any of these can also live in a .gitaiflow.env file in your repo root instead of real environment variables (same KEY=value format). If nothing is configured, gitaiflow fails fast with these same instructions rather than partway through a run.

Full config reference:

Variable Default Notes
AI_PROVIDER gemini gemini | ollama | openai | custom
AI_BASE_URL provider default override for any provider
AI_API_KEY (none) required for gemini/openai/custom; not needed for ollama
AI_MODEL provider default e.g. gemini-flash-lite-latest, llama3.2:3b, gpt-4.1-mini
AI_TEMPERATURE 0.2
AI_MAX_TOKENS 10000
AI_REQUEST_TIMEOUT 60 seconds

Usage

gitaiflow --path mailer/                        # summarize a directory
gitaiflow --path users/views/logout.py           # summarize a single file
gitaiflow --path . --skip migrations tests       # skip paths
gitaiflow --path . --remote upstream --base-branch develop
gitaiflow --path . -o artifacts/                 # custom output root
gitaiflow --path . --markdown                    # also write a .md view
gitaiflow --path . --print-commit                # print title+body to stdout

--print-commit is meant to be piped straight into git:

gitaiflow --path . --print-commit > /tmp/msg.txt && git commit -F /tmp/msg.txt

Output

Every run writes one JSON file to change-summary/json/<target>-<timestamp>.json:

{
  "generated_at": "2026-08-19T14:32:07+05:30",
  "target": "mailer",
  "target_type": "directory",
  "repository": "paystream",
  "branch": "feature/mailer-retry",
  "base": "origin/main",
  "author": { "name": "Chandrashekhar Bhosale", "email": "shekhar@djangoplay.org" },
  "change_window": {
    "first_change_at": "2026-08-18 09:12:03",
    "last_change_at": "2026-08-19 14:30:11"
  },
  "files_changed": [
    { "path": "mailer/tasks.py", "status": "modified" },
    { "path": "mailer/retry.py", "status": "added" }
  ],
  "model": { "provider": "gemini", "name": "gemini-flash-lite-latest" },
  "commit": {
    "title": "mailer: add retry backoff for failed sends",
    "body": "- Added exponential backoff retry logic in retry.py\n- tasks.py now retries send_mail up to 3 times on failure\n- No changes to public function signatures"
  },
  "summary": "(same content as commit.body)"
}

author, branch, base, change_window, and files_changed come straight from git -- never from the model -- so they're accurate even if the AI call fails or hallucinates. commit.title / commit.body are the only model-generated fields, and they're the ones designed to be commit-ready as-is.

--markdown renders a second, human-facing view from the same JSON into change-summary/markdown/ -- the JSON is always the source of truth.

Local usage log

Every run appends one line to ~/.gitaiflow/usage.jsonl -- timestamp, repo name, target type, model used, estimated token counts, duration, success. This file never leaves your machine. It exists so you can see your own usage and, optionally, set soft daily limits:

export GITAIFLOW_MAX_RUNS_PER_DAY=20
export GITAIFLOW_MAX_TOKENS_PER_DAY=50000

When set, gitaiflow prints a warning once you've crossed the threshold for the day. This is a courtesy guardrail against accidentally running up a cloud-model bill, not enforcement -- it's a local file, and any user can clear it.

Repository layout

telemetry_server/ lives inside this same repo, at the root, next to the gitaiflow/ package.

gitaiflow/                    (repo root)
├── gitaiflow/                <- the PyPI package (this is what `pip install gitaiflow` installs)
│   ├── config/
│   ├── services/
│   ├── prompts/
│   └── generate_summary.py   <- CLI entry point
├── telemetry_server/         <- standalone Flask receiver, deployed separately to
│   ├── app.py                   host server, for example, `app.djangoplay.org`
│   ├── requirements.txt
├── .gitlab-ci.yml
├── .gitlab/ci/
│   ├── pypi-release.yml      <- test -> build -> version-check -> publish (manual, main only)
│   ├── github-mirror.yml     <- mirrors main to GitHub on every push
│   └── deploy-telemetry.yml  <- deploys telemetry_server/ to production (manual, main only)
├── .github/workflows/gitlab-mirror.yml
├── pyproject.toml
└── README.md                 <- this file

Two independent things ship from this one repo: the gitaiflow PyPI package (what end users pip install), and the telemetry receiver (a small internal service you run, not part of the package). They share a repo and a CI pipeline but nothing else at runtime.

Telemetry (opt-in, off by default)

gitaiflow does not phone home by default. If you explicitly set:

export GITAIFLOW_TELEMETRY=true

then each run sends exactly below details, to configured telemetry receiver https://app.djangoplay.org/gitaiflow-telemetry/v1/events (the maintainer's self-hosted receiver), and nothing else:

Field Example
install_id random UUID, generated once locally
event "run"
timestamp 2026-08-19T14:32:07Z
gitaiflow_version "1.0.0"
ai_provider "gemini"
model_name "gemini-flash-lite-latest"
target_type "file" | "directory"
files_changed_count 4
tokens_estimated_in / tokens_estimated_out 1832 / 210
duration_ms 2140
success true
os "linux"

🔒 NEVER SENT, EVEN WITH TELEMETRY ON: repository name, file paths, file contents, diff content, Git author/branch, commit messages, or the AI-generated summary text.

On the first telemetry-enabled run, Gitaiflow prints the exact payload to stdout so this is verifiable, not just promised.

Limitations

  • An AI provider is mandatory -- gitaiflow does nothing without one configured, by design (see "Configure an AI provider" above).

  • Daily run/token limits are a local, deletable courtesy check, not real enforcement. There's no license/quota server behind them.

  • Secret redaction (.env, *_API_KEY, *_SECRET_KEY, etc.) is best-effort pattern matching on the diff -- always review generated summaries before sharing them outside your team.

  • Token/cost estimates in the usage log are a rough len(text) / 4 heuristic, not provider-accurate billing.

  • Hosted model-routing backend for a future paid tier.

  • Server-side license/quota enforcement.

  • PR-platform integration (auto-post summaries to GitHub/GitLab).

  • Diff/summary caching across runs.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

gitaiflow-1.0.1.tar.gz (33.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

gitaiflow-1.0.1-py3-none-any.whl (33.9 kB view details)

Uploaded Python 3

File details

Details for the file gitaiflow-1.0.1.tar.gz.

File metadata

  • Download URL: gitaiflow-1.0.1.tar.gz
  • Upload date:
  • Size: 33.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.11.16

File hashes

Hashes for gitaiflow-1.0.1.tar.gz
Algorithm Hash digest
SHA256 ddc5d9c7e7f75d44ded139cba0827a597a5d88d25afa5f5384560b1467326af1
MD5 4f4c2dcf5ba1900c835c6dd0eaba8200
BLAKE2b-256 1c0548a64035e4c32ff3eeef9a609d670d32edb5f07212c64016eea540484fef

See more details on using hashes here.

File details

Details for the file gitaiflow-1.0.1-py3-none-any.whl.

File metadata

  • Download URL: gitaiflow-1.0.1-py3-none-any.whl
  • Upload date:
  • Size: 33.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.11.16

File hashes

Hashes for gitaiflow-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 dd46abce84a73e29f94769eab045f2babb5a84fbaa0355af33d7651c558efe52
MD5 1ea37dc4867f9ec2f06bc91ba21ae44b
BLAKE2b-256 882887aed4935bd8272fcf11c9377cd2c918de8475323c7900835d76efcc5f1e

See more details on using hashes here.

Release history Release notifications | RSS feed

1.0.2

2 files

This release

1.0.1 This release

2 files

1.0.0

2 files

0.1.2

2 files

0.1.1

2 files

0.1.0

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page