commitgpt-nikesh 1.0.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.
@@ -0,0 +1,272 @@
1
+ Metadata-Version: 2.4
2
+ Name: commitgpt-nikesh
3
+ Version: 1.0.0
4
+ Summary: AI-powered commit messages, standups and PR descriptions from your git diff
5
+ Home-page: https://github.com/nikeshsundar/commitgpt
6
+ Author: Nikesh Sundar
7
+ Author-email: nikeshsundar@users.noreply.github.com
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Operating System :: OS Independent
11
+ Requires-Python: >=3.9
12
+ Description-Content-Type: text/markdown
13
+ Requires-Dist: click
14
+ Requires-Dist: openai>=1.0.0
15
+ Requires-Dist: pyperclip
16
+ Requires-Dist: python-dotenv
17
+ Dynamic: author
18
+ Dynamic: author-email
19
+ Dynamic: classifier
20
+ Dynamic: description
21
+ Dynamic: description-content-type
22
+ Dynamic: home-page
23
+ Dynamic: requires-dist
24
+ Dynamic: requires-python
25
+ Dynamic: summary
26
+
27
+ # commitgpt ⚡
28
+
29
+ > AI-powered commit messages, standups, and PR descriptions — generated from your git diff in 2 seconds.
30
+
31
+ ![PyPI](https://img.shields.io/pypi/v/commitgpt)
32
+ ![Python](https://img.shields.io/pypi/pyversions/commitgpt)
33
+ ![License](https://img.shields.io/github/license/yourusername/commitgpt)
34
+
35
+ ---
36
+
37
+ ## The problem
38
+
39
+ Every day as a developer you waste time writing:
40
+
41
+ - `git commit -m "fix"` — lazy, meaningless commit messages
42
+ - Standup updates — "what did I do yesterday??"
43
+ - PR descriptions — explaining your changes all over again
44
+
45
+ **commitgpt fixes all 3 with one command.**
46
+
47
+ ---
48
+
49
+ ## Demo
50
+ ```
51
+ $ git add .
52
+ $ cmt
53
+
54
+ ✨ feat(auth): add Google OAuth2 login with session timeout
55
+
56
+ - Implemented OAuth2 flow using Google provider
57
+ - Sessions expire after 30 mins of inactivity
58
+ - Fixed bug where users stayed logged in after password change
59
+ - Added redirect to dashboard on successful login
60
+ ```
61
+
62
+ ---
63
+
64
+ ## Install
65
+ ```bash
66
+ pip install commitgpt
67
+ ```
68
+
69
+ ---
70
+
71
+ ## Setup
72
+
73
+ You only need ONE of these. Pick whichever you prefer:
74
+
75
+ ---
76
+
77
+ ### Option 1 — GitHub Token (FREE, recommended)
78
+
79
+ Best for beginners. No credit card. 150 requests/day free.
80
+
81
+ - Go to [github.com](https://github.com) → Settings
82
+ - Click **Developer Settings** → **Personal Access Tokens** → **Tokens (classic)**
83
+ - Click **Generate new token (classic)**
84
+ - Give it any name, no scopes needed
85
+ - Copy the token starting with `ghp_`
86
+
87
+ Create a `.env` file in your project:
88
+ ```
89
+ GITHUB_TOKEN=ghp_your_token_here
90
+ ```
91
+
92
+ ---
93
+
94
+ ### Option 2 — Gemini (FREE, best free option)
95
+
96
+ Best free option. 1,500 requests/day free. No credit card.
97
+
98
+ - Go to [aistudio.google.com](https://aistudio.google.com)
99
+ - Click **Get API Key** → **Create API key**
100
+ - Copy the key starting with `AIza`
101
+
102
+ Create a `.env` file in your project:
103
+ ```
104
+ GEMINI_API_KEY=AIza_your_key_here
105
+ ```
106
+
107
+ ---
108
+
109
+ ### Option 3 — OpenAI (Paid)
110
+
111
+ Best quality. Costs roughly $0.001 per request.
112
+
113
+ - Go to [platform.openai.com](https://platform.openai.com)
114
+ - Click **API Keys** → **Create new secret key**
115
+ - Copy the key starting with `sk-proj-`
116
+
117
+ Create a `.env` file in your project:
118
+ ```
119
+ OPENAI_API_KEY=sk-proj-your_key_here
120
+ ```
121
+
122
+ ---
123
+
124
+ ### Option 4 — Anthropic Claude (Paid)
125
+
126
+ Great quality. Costs roughly $0.001 per request.
127
+
128
+ - Go to [console.anthropic.com](https://console.anthropic.com)
129
+ - Click **API Keys** → **Create Key**
130
+ - Copy the key starting with `sk-ant-`
131
+
132
+ Create a `.env` file in your project:
133
+ ```
134
+ ANTHROPIC_API_KEY=sk-ant-your_key_here
135
+ ```
136
+
137
+ ---
138
+
139
+ ### Make your token permanent
140
+
141
+ So you never have to set it again every time you open terminal:
142
+
143
+ **Mac/Linux:**
144
+ ```bash
145
+ echo 'export GITHUB_TOKEN=ghp_yourtoken' >> ~/.zshrc
146
+ source ~/.zshrc
147
+ ```
148
+
149
+ **Windows:**
150
+ ```bash
151
+ setx GITHUB_TOKEN "ghp_yourtoken"
152
+ ```
153
+
154
+ ---
155
+
156
+ ## Usage
157
+
158
+ ### Commit message
159
+ ```bash
160
+ git add .
161
+ cmt
162
+ ```
163
+
164
+ ### Daily standup
165
+ ```bash
166
+ cmt standup
167
+ ```
168
+ Output:
169
+ ```
170
+ Yesterday: Implemented OAuth2 login flow, fixed session expiry bug
171
+ Today: Writing tests for auth middleware, reviewing PR #42
172
+ Blockers: None
173
+ ```
174
+
175
+ ### PR description
176
+ ```bash
177
+ cmt pr
178
+ ```
179
+ Output:
180
+ ```
181
+ ## What changed
182
+ Added Google OAuth2 login with automatic session timeout after 30 minutes.
183
+
184
+ ## Why
185
+ Users were being kept logged in indefinitely, creating a security risk.
186
+
187
+ ## Testing
188
+ - Manual: tested login, logout, session expiry
189
+ - Unit: auth middleware coverage at 94%
190
+ - Edge: concurrent login sessions handled correctly
191
+ ```
192
+
193
+ ### Extra flags
194
+ ```bash
195
+ cmt --emoji # adds emoji to commit message
196
+ cmt --copy # copies output to clipboard automatically
197
+ ```
198
+
199
+ ---
200
+
201
+ ## How the tool picks your API
202
+
203
+ You don't need to configure anything. Just put your key in `.env` and the tool automatically detects it in this order:
204
+ ```
205
+ GITHUB_TOKEN → GitHub Models (gpt-4o-mini)
206
+ GEMINI_API_KEY → Gemini 2.0 Flash
207
+ OPENAI_API_KEY → OpenAI gpt-4o-mini
208
+ ANTHROPIC_API_KEY → Claude Haiku
209
+ ```
210
+
211
+ First key found = that provider gets used.
212
+
213
+ ---
214
+
215
+ ## Requirements
216
+
217
+ - Python 3.8+
218
+ - Git installed
219
+ - Any one API key from the options above
220
+
221
+ ---
222
+
223
+ ## Troubleshooting
224
+
225
+ **`cmt: command not found`**
226
+ ```bash
227
+ pip install commitgpt
228
+ ```
229
+
230
+ **`Error: No API key found`**
231
+ Make sure your `.env` file exists with one of these:
232
+ ```
233
+ GITHUB_TOKEN=ghp_...
234
+ GEMINI_API_KEY=AIza...
235
+ OPENAI_API_KEY=sk-proj-...
236
+ ANTHROPIC_API_KEY=sk-ant-...
237
+ ```
238
+
239
+ **`Not a git repository`**
240
+ You need to be inside a git project. Run `git init` first.
241
+
242
+ **`No staged changes found`**
243
+ Run `git add .` before running `cmt`
244
+
245
+ **`pip install fails`**
246
+ Make sure Python 3.8+ is installed:
247
+ ```bash
248
+ python --version
249
+ ```
250
+
251
+ ---
252
+
253
+ ## Contributing
254
+
255
+ Pull requests are welcome! Here's how:
256
+
257
+ 1. Fork the repo
258
+ 2. Create a branch: `git checkout -b feat/your-feature`
259
+ 3. Make your changes
260
+ 4. Use commitgpt to write your own commit message 😄
261
+ 5. Push and open a PR
262
+
263
+ ---
264
+
265
+ ## License
266
+
267
+ MIT — free to use, modify and distribute.
268
+
269
+ ---
270
+
271
+ Made by a developer who was tired of writing "fix" as a commit message.
272
+
@@ -0,0 +1,246 @@
1
+ # commitgpt ⚡
2
+
3
+ > AI-powered commit messages, standups, and PR descriptions — generated from your git diff in 2 seconds.
4
+
5
+ ![PyPI](https://img.shields.io/pypi/v/commitgpt)
6
+ ![Python](https://img.shields.io/pypi/pyversions/commitgpt)
7
+ ![License](https://img.shields.io/github/license/yourusername/commitgpt)
8
+
9
+ ---
10
+
11
+ ## The problem
12
+
13
+ Every day as a developer you waste time writing:
14
+
15
+ - `git commit -m "fix"` — lazy, meaningless commit messages
16
+ - Standup updates — "what did I do yesterday??"
17
+ - PR descriptions — explaining your changes all over again
18
+
19
+ **commitgpt fixes all 3 with one command.**
20
+
21
+ ---
22
+
23
+ ## Demo
24
+ ```
25
+ $ git add .
26
+ $ cmt
27
+
28
+ ✨ feat(auth): add Google OAuth2 login with session timeout
29
+
30
+ - Implemented OAuth2 flow using Google provider
31
+ - Sessions expire after 30 mins of inactivity
32
+ - Fixed bug where users stayed logged in after password change
33
+ - Added redirect to dashboard on successful login
34
+ ```
35
+
36
+ ---
37
+
38
+ ## Install
39
+ ```bash
40
+ pip install commitgpt
41
+ ```
42
+
43
+ ---
44
+
45
+ ## Setup
46
+
47
+ You only need ONE of these. Pick whichever you prefer:
48
+
49
+ ---
50
+
51
+ ### Option 1 — GitHub Token (FREE, recommended)
52
+
53
+ Best for beginners. No credit card. 150 requests/day free.
54
+
55
+ - Go to [github.com](https://github.com) → Settings
56
+ - Click **Developer Settings** → **Personal Access Tokens** → **Tokens (classic)**
57
+ - Click **Generate new token (classic)**
58
+ - Give it any name, no scopes needed
59
+ - Copy the token starting with `ghp_`
60
+
61
+ Create a `.env` file in your project:
62
+ ```
63
+ GITHUB_TOKEN=ghp_your_token_here
64
+ ```
65
+
66
+ ---
67
+
68
+ ### Option 2 — Gemini (FREE, best free option)
69
+
70
+ Best free option. 1,500 requests/day free. No credit card.
71
+
72
+ - Go to [aistudio.google.com](https://aistudio.google.com)
73
+ - Click **Get API Key** → **Create API key**
74
+ - Copy the key starting with `AIza`
75
+
76
+ Create a `.env` file in your project:
77
+ ```
78
+ GEMINI_API_KEY=AIza_your_key_here
79
+ ```
80
+
81
+ ---
82
+
83
+ ### Option 3 — OpenAI (Paid)
84
+
85
+ Best quality. Costs roughly $0.001 per request.
86
+
87
+ - Go to [platform.openai.com](https://platform.openai.com)
88
+ - Click **API Keys** → **Create new secret key**
89
+ - Copy the key starting with `sk-proj-`
90
+
91
+ Create a `.env` file in your project:
92
+ ```
93
+ OPENAI_API_KEY=sk-proj-your_key_here
94
+ ```
95
+
96
+ ---
97
+
98
+ ### Option 4 — Anthropic Claude (Paid)
99
+
100
+ Great quality. Costs roughly $0.001 per request.
101
+
102
+ - Go to [console.anthropic.com](https://console.anthropic.com)
103
+ - Click **API Keys** → **Create Key**
104
+ - Copy the key starting with `sk-ant-`
105
+
106
+ Create a `.env` file in your project:
107
+ ```
108
+ ANTHROPIC_API_KEY=sk-ant-your_key_here
109
+ ```
110
+
111
+ ---
112
+
113
+ ### Make your token permanent
114
+
115
+ So you never have to set it again every time you open terminal:
116
+
117
+ **Mac/Linux:**
118
+ ```bash
119
+ echo 'export GITHUB_TOKEN=ghp_yourtoken' >> ~/.zshrc
120
+ source ~/.zshrc
121
+ ```
122
+
123
+ **Windows:**
124
+ ```bash
125
+ setx GITHUB_TOKEN "ghp_yourtoken"
126
+ ```
127
+
128
+ ---
129
+
130
+ ## Usage
131
+
132
+ ### Commit message
133
+ ```bash
134
+ git add .
135
+ cmt
136
+ ```
137
+
138
+ ### Daily standup
139
+ ```bash
140
+ cmt standup
141
+ ```
142
+ Output:
143
+ ```
144
+ Yesterday: Implemented OAuth2 login flow, fixed session expiry bug
145
+ Today: Writing tests for auth middleware, reviewing PR #42
146
+ Blockers: None
147
+ ```
148
+
149
+ ### PR description
150
+ ```bash
151
+ cmt pr
152
+ ```
153
+ Output:
154
+ ```
155
+ ## What changed
156
+ Added Google OAuth2 login with automatic session timeout after 30 minutes.
157
+
158
+ ## Why
159
+ Users were being kept logged in indefinitely, creating a security risk.
160
+
161
+ ## Testing
162
+ - Manual: tested login, logout, session expiry
163
+ - Unit: auth middleware coverage at 94%
164
+ - Edge: concurrent login sessions handled correctly
165
+ ```
166
+
167
+ ### Extra flags
168
+ ```bash
169
+ cmt --emoji # adds emoji to commit message
170
+ cmt --copy # copies output to clipboard automatically
171
+ ```
172
+
173
+ ---
174
+
175
+ ## How the tool picks your API
176
+
177
+ You don't need to configure anything. Just put your key in `.env` and the tool automatically detects it in this order:
178
+ ```
179
+ GITHUB_TOKEN → GitHub Models (gpt-4o-mini)
180
+ GEMINI_API_KEY → Gemini 2.0 Flash
181
+ OPENAI_API_KEY → OpenAI gpt-4o-mini
182
+ ANTHROPIC_API_KEY → Claude Haiku
183
+ ```
184
+
185
+ First key found = that provider gets used.
186
+
187
+ ---
188
+
189
+ ## Requirements
190
+
191
+ - Python 3.8+
192
+ - Git installed
193
+ - Any one API key from the options above
194
+
195
+ ---
196
+
197
+ ## Troubleshooting
198
+
199
+ **`cmt: command not found`**
200
+ ```bash
201
+ pip install commitgpt
202
+ ```
203
+
204
+ **`Error: No API key found`**
205
+ Make sure your `.env` file exists with one of these:
206
+ ```
207
+ GITHUB_TOKEN=ghp_...
208
+ GEMINI_API_KEY=AIza...
209
+ OPENAI_API_KEY=sk-proj-...
210
+ ANTHROPIC_API_KEY=sk-ant-...
211
+ ```
212
+
213
+ **`Not a git repository`**
214
+ You need to be inside a git project. Run `git init` first.
215
+
216
+ **`No staged changes found`**
217
+ Run `git add .` before running `cmt`
218
+
219
+ **`pip install fails`**
220
+ Make sure Python 3.8+ is installed:
221
+ ```bash
222
+ python --version
223
+ ```
224
+
225
+ ---
226
+
227
+ ## Contributing
228
+
229
+ Pull requests are welcome! Here's how:
230
+
231
+ 1. Fork the repo
232
+ 2. Create a branch: `git checkout -b feat/your-feature`
233
+ 3. Make your changes
234
+ 4. Use commitgpt to write your own commit message 😄
235
+ 5. Push and open a PR
236
+
237
+ ---
238
+
239
+ ## License
240
+
241
+ MIT — free to use, modify and distribute.
242
+
243
+ ---
244
+
245
+ Made by a developer who was tired of writing "fix" as a commit message.
246
+
@@ -0,0 +1,2 @@
1
+ __all__ = ["__version__"]
2
+ __version__ = "0.1.0"
@@ -0,0 +1,46 @@
1
+ import os
2
+ from pathlib import Path
3
+ from openai import OpenAI
4
+ from dotenv import load_dotenv
5
+
6
+ class AIError(RuntimeError):
7
+ pass
8
+
9
+ def get_api_key() -> str:
10
+ key = os.getenv("OPENAI_API_KEY")
11
+ if key:
12
+ return key
13
+
14
+ load_dotenv()
15
+ key = os.getenv("OPENAI_API_KEY")
16
+ if key:
17
+ return key
18
+
19
+ config_path = Path.home() / ".commitgpt"
20
+ if config_path.exists():
21
+ key = config_path.read_text().strip()
22
+ if key:
23
+ return key
24
+
25
+ raise AIError("OPENAI_API_KEY environment variable is not set, and ~/.commitgpt is missing or empty.")
26
+
27
+
28
+ def generate_text(system_prompt: str, user_prompt: str, emoji: bool = False) -> str:
29
+ try:
30
+ api_key = get_api_key()
31
+ client = OpenAI(api_key=api_key)
32
+
33
+ if emoji:
34
+ system_prompt += "\nAlso add an appropriate emoji at the start of the commit message."
35
+
36
+ response = client.chat.completions.create(
37
+ model="gpt-4o-mini",
38
+ messages=[
39
+ {"role": "system", "content": system_prompt},
40
+ {"role": "user", "content": user_prompt}
41
+ ],
42
+ temperature=0.3,
43
+ )
44
+ return response.choices[0].message.content.strip()
45
+ except Exception as e:
46
+ raise AIError(f"OpenAI API Error: {str(e)}")
@@ -0,0 +1,78 @@
1
+ import sys
2
+ import click
3
+ import pyperclip
4
+ from dotenv import load_dotenv
5
+
6
+ from .git import get_staged_diff, get_recent_log, get_pr_diff, GitError
7
+ from .ai import generate_text, AIError
8
+ from .prompts import COMMIT_PROMPT, STANDUP_PROMPT, PR_PROMPT
9
+
10
+ load_dotenv()
11
+
12
+ @click.group(invoke_without_command=True)
13
+ @click.option('--copy', is_flag=True, help="Copy output to clipboard")
14
+ @click.option('--emoji', is_flag=True, help="Add emoji to commit message")
15
+ @click.pass_context
16
+ def cli(ctx, copy, emoji):
17
+ """CommitGPT: Auto-generate commit messages, standups, and PR descriptions."""
18
+ if ctx.invoked_subcommand is None:
19
+ generate_commit(copy, emoji)
20
+ else:
21
+ ctx.ensure_object(dict)
22
+ ctx.obj['copy'] = copy
23
+ ctx.obj['emoji'] = emoji
24
+
25
+
26
+ def generate_commit(copy: bool, emoji: bool):
27
+ try:
28
+ diff = get_staged_diff()
29
+ click.echo("Generating commit message...")
30
+ message = generate_text(COMMIT_PROMPT, diff, emoji=emoji)
31
+ click.echo("\n" + message + "\n")
32
+ if copy:
33
+ pyperclip.copy(message)
34
+ click.echo("Copied to clipboard!")
35
+ except (GitError, AIError) as e:
36
+ click.echo(f"Error: {str(e)}", err=True)
37
+ sys.exit(1)
38
+
39
+ @cli.command()
40
+ @click.pass_context
41
+ def standup(ctx):
42
+ """Generate a daily standup based on last 24h commits."""
43
+ try:
44
+ log = get_recent_log()
45
+ click.echo("Generating standup...")
46
+ message = generate_text(STANDUP_PROMPT, log)
47
+ click.echo("\n" + message + "\n")
48
+ if ctx.obj.get('copy'):
49
+ pyperclip.copy(message)
50
+ click.echo("Copied to clipboard!")
51
+ except (GitError, AIError) as e:
52
+ click.echo(f"Error: {str(e)}", err=True)
53
+ sys.exit(1)
54
+
55
+
56
+ @cli.command()
57
+ @click.pass_context
58
+ def pr(ctx):
59
+ """Generate a PR description from diff main...HEAD."""
60
+ try:
61
+ diff = get_pr_diff()
62
+ click.echo("Generating PR description...")
63
+ message = generate_text(PR_PROMPT, diff)
64
+ click.echo("\n" + message + "\n")
65
+ if ctx.obj.get('copy'):
66
+ pyperclip.copy(message)
67
+ click.echo("Copied to clipboard!")
68
+ except (GitError, AIError) as e:
69
+ click.echo(f"Error: {str(e)}", err=True)
70
+ sys.exit(1)
71
+
72
+
73
+ def main():
74
+ cli(obj={})
75
+
76
+
77
+ if __name__ == "__main__":
78
+ main()
@@ -0,0 +1,40 @@
1
+ import subprocess
2
+
3
+ class GitError(RuntimeError):
4
+ pass
5
+
6
+ def _run_git(args: list[str]) -> str:
7
+ try:
8
+ subprocess.run(["git", "rev-parse", "--is-inside-work-tree"], capture_output=True, check=True)
9
+ except subprocess.CalledProcessError:
10
+ raise GitError("Not in a git repository.")
11
+
12
+ process = subprocess.run(["git", *args], capture_output=True, text=True)
13
+ if process.returncode != 0:
14
+ raise GitError(process.stderr.strip() or "Unknown git error")
15
+ return process.stdout.strip()
16
+
17
+ def get_staged_diff() -> str:
18
+ diff = _run_git(["diff", "--staged"])
19
+ if not diff:
20
+ raise GitError("No staged changes found. Did you forget to git add?")
21
+ return diff
22
+
23
+ def get_recent_log() -> str:
24
+ log = _run_git(["log", "--since=24 hours ago", "--oneline"])
25
+ if not log:
26
+ raise GitError("No commits found in the last 24 hours.")
27
+ return log
28
+
29
+ def get_pr_diff() -> str:
30
+ try:
31
+ diff = _run_git(["diff", "main...HEAD"])
32
+ except GitError:
33
+ try:
34
+ diff = _run_git(["diff", "master...HEAD"])
35
+ except GitError:
36
+ raise GitError("Could not diff against main or master.")
37
+
38
+ if not diff:
39
+ raise GitError("No differences found between main/master and HEAD.")
40
+ return diff
@@ -0,0 +1,5 @@
1
+ COMMIT_PROMPT = """You are an expert developer. Given this git diff, write a single conventional \ncommit message. Format: type(scope): description. Types: feat/fix/docs/style/\nrefactor/test/chore. Keep under 72 chars. Then add 2-4 bullet points explaining \nkey changes. Output ONLY the commit message and bullets, nothing else."""
2
+
3
+ STANDUP_PROMPT = """You are a developer writing a daily standup. Given these git commits from the \nlast 24 hours, generate a standup update. Format exactly:\nYesterday: [what was done, past tense, concise]\nToday: [logical next steps based on the work]\nBlockers: [say None if nothing obvious]\nBe specific about what changed. Output ONLY the standup, nothing else."""
4
+
5
+ PR_PROMPT = """You are an expert developer. Given this git diff between branches, write a \ncomplete QR description. Format exactly:\n## What changed\n[2-3 sentences]\n## Why\n[reason for the change]\n## Testing\n[how to test this]\n## Checklist\n- [ ] Tests added\n- [ ] Docs updated\nOutput ONLY the QR description markdown, nothing else."""
@@ -0,0 +1,272 @@
1
+ Metadata-Version: 2.4
2
+ Name: commitgpt-nikesh
3
+ Version: 1.0.0
4
+ Summary: AI-powered commit messages, standups and PR descriptions from your git diff
5
+ Home-page: https://github.com/nikeshsundar/commitgpt
6
+ Author: Nikesh Sundar
7
+ Author-email: nikeshsundar@users.noreply.github.com
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Operating System :: OS Independent
11
+ Requires-Python: >=3.9
12
+ Description-Content-Type: text/markdown
13
+ Requires-Dist: click
14
+ Requires-Dist: openai>=1.0.0
15
+ Requires-Dist: pyperclip
16
+ Requires-Dist: python-dotenv
17
+ Dynamic: author
18
+ Dynamic: author-email
19
+ Dynamic: classifier
20
+ Dynamic: description
21
+ Dynamic: description-content-type
22
+ Dynamic: home-page
23
+ Dynamic: requires-dist
24
+ Dynamic: requires-python
25
+ Dynamic: summary
26
+
27
+ # commitgpt ⚡
28
+
29
+ > AI-powered commit messages, standups, and PR descriptions — generated from your git diff in 2 seconds.
30
+
31
+ ![PyPI](https://img.shields.io/pypi/v/commitgpt)
32
+ ![Python](https://img.shields.io/pypi/pyversions/commitgpt)
33
+ ![License](https://img.shields.io/github/license/yourusername/commitgpt)
34
+
35
+ ---
36
+
37
+ ## The problem
38
+
39
+ Every day as a developer you waste time writing:
40
+
41
+ - `git commit -m "fix"` — lazy, meaningless commit messages
42
+ - Standup updates — "what did I do yesterday??"
43
+ - PR descriptions — explaining your changes all over again
44
+
45
+ **commitgpt fixes all 3 with one command.**
46
+
47
+ ---
48
+
49
+ ## Demo
50
+ ```
51
+ $ git add .
52
+ $ cmt
53
+
54
+ ✨ feat(auth): add Google OAuth2 login with session timeout
55
+
56
+ - Implemented OAuth2 flow using Google provider
57
+ - Sessions expire after 30 mins of inactivity
58
+ - Fixed bug where users stayed logged in after password change
59
+ - Added redirect to dashboard on successful login
60
+ ```
61
+
62
+ ---
63
+
64
+ ## Install
65
+ ```bash
66
+ pip install commitgpt
67
+ ```
68
+
69
+ ---
70
+
71
+ ## Setup
72
+
73
+ You only need ONE of these. Pick whichever you prefer:
74
+
75
+ ---
76
+
77
+ ### Option 1 — GitHub Token (FREE, recommended)
78
+
79
+ Best for beginners. No credit card. 150 requests/day free.
80
+
81
+ - Go to [github.com](https://github.com) → Settings
82
+ - Click **Developer Settings** → **Personal Access Tokens** → **Tokens (classic)**
83
+ - Click **Generate new token (classic)**
84
+ - Give it any name, no scopes needed
85
+ - Copy the token starting with `ghp_`
86
+
87
+ Create a `.env` file in your project:
88
+ ```
89
+ GITHUB_TOKEN=ghp_your_token_here
90
+ ```
91
+
92
+ ---
93
+
94
+ ### Option 2 — Gemini (FREE, best free option)
95
+
96
+ Best free option. 1,500 requests/day free. No credit card.
97
+
98
+ - Go to [aistudio.google.com](https://aistudio.google.com)
99
+ - Click **Get API Key** → **Create API key**
100
+ - Copy the key starting with `AIza`
101
+
102
+ Create a `.env` file in your project:
103
+ ```
104
+ GEMINI_API_KEY=AIza_your_key_here
105
+ ```
106
+
107
+ ---
108
+
109
+ ### Option 3 — OpenAI (Paid)
110
+
111
+ Best quality. Costs roughly $0.001 per request.
112
+
113
+ - Go to [platform.openai.com](https://platform.openai.com)
114
+ - Click **API Keys** → **Create new secret key**
115
+ - Copy the key starting with `sk-proj-`
116
+
117
+ Create a `.env` file in your project:
118
+ ```
119
+ OPENAI_API_KEY=sk-proj-your_key_here
120
+ ```
121
+
122
+ ---
123
+
124
+ ### Option 4 — Anthropic Claude (Paid)
125
+
126
+ Great quality. Costs roughly $0.001 per request.
127
+
128
+ - Go to [console.anthropic.com](https://console.anthropic.com)
129
+ - Click **API Keys** → **Create Key**
130
+ - Copy the key starting with `sk-ant-`
131
+
132
+ Create a `.env` file in your project:
133
+ ```
134
+ ANTHROPIC_API_KEY=sk-ant-your_key_here
135
+ ```
136
+
137
+ ---
138
+
139
+ ### Make your token permanent
140
+
141
+ So you never have to set it again every time you open terminal:
142
+
143
+ **Mac/Linux:**
144
+ ```bash
145
+ echo 'export GITHUB_TOKEN=ghp_yourtoken' >> ~/.zshrc
146
+ source ~/.zshrc
147
+ ```
148
+
149
+ **Windows:**
150
+ ```bash
151
+ setx GITHUB_TOKEN "ghp_yourtoken"
152
+ ```
153
+
154
+ ---
155
+
156
+ ## Usage
157
+
158
+ ### Commit message
159
+ ```bash
160
+ git add .
161
+ cmt
162
+ ```
163
+
164
+ ### Daily standup
165
+ ```bash
166
+ cmt standup
167
+ ```
168
+ Output:
169
+ ```
170
+ Yesterday: Implemented OAuth2 login flow, fixed session expiry bug
171
+ Today: Writing tests for auth middleware, reviewing PR #42
172
+ Blockers: None
173
+ ```
174
+
175
+ ### PR description
176
+ ```bash
177
+ cmt pr
178
+ ```
179
+ Output:
180
+ ```
181
+ ## What changed
182
+ Added Google OAuth2 login with automatic session timeout after 30 minutes.
183
+
184
+ ## Why
185
+ Users were being kept logged in indefinitely, creating a security risk.
186
+
187
+ ## Testing
188
+ - Manual: tested login, logout, session expiry
189
+ - Unit: auth middleware coverage at 94%
190
+ - Edge: concurrent login sessions handled correctly
191
+ ```
192
+
193
+ ### Extra flags
194
+ ```bash
195
+ cmt --emoji # adds emoji to commit message
196
+ cmt --copy # copies output to clipboard automatically
197
+ ```
198
+
199
+ ---
200
+
201
+ ## How the tool picks your API
202
+
203
+ You don't need to configure anything. Just put your key in `.env` and the tool automatically detects it in this order:
204
+ ```
205
+ GITHUB_TOKEN → GitHub Models (gpt-4o-mini)
206
+ GEMINI_API_KEY → Gemini 2.0 Flash
207
+ OPENAI_API_KEY → OpenAI gpt-4o-mini
208
+ ANTHROPIC_API_KEY → Claude Haiku
209
+ ```
210
+
211
+ First key found = that provider gets used.
212
+
213
+ ---
214
+
215
+ ## Requirements
216
+
217
+ - Python 3.8+
218
+ - Git installed
219
+ - Any one API key from the options above
220
+
221
+ ---
222
+
223
+ ## Troubleshooting
224
+
225
+ **`cmt: command not found`**
226
+ ```bash
227
+ pip install commitgpt
228
+ ```
229
+
230
+ **`Error: No API key found`**
231
+ Make sure your `.env` file exists with one of these:
232
+ ```
233
+ GITHUB_TOKEN=ghp_...
234
+ GEMINI_API_KEY=AIza...
235
+ OPENAI_API_KEY=sk-proj-...
236
+ ANTHROPIC_API_KEY=sk-ant-...
237
+ ```
238
+
239
+ **`Not a git repository`**
240
+ You need to be inside a git project. Run `git init` first.
241
+
242
+ **`No staged changes found`**
243
+ Run `git add .` before running `cmt`
244
+
245
+ **`pip install fails`**
246
+ Make sure Python 3.8+ is installed:
247
+ ```bash
248
+ python --version
249
+ ```
250
+
251
+ ---
252
+
253
+ ## Contributing
254
+
255
+ Pull requests are welcome! Here's how:
256
+
257
+ 1. Fork the repo
258
+ 2. Create a branch: `git checkout -b feat/your-feature`
259
+ 3. Make your changes
260
+ 4. Use commitgpt to write your own commit message 😄
261
+ 5. Push and open a PR
262
+
263
+ ---
264
+
265
+ ## License
266
+
267
+ MIT — free to use, modify and distribute.
268
+
269
+ ---
270
+
271
+ Made by a developer who was tired of writing "fix" as a commit message.
272
+
@@ -0,0 +1,13 @@
1
+ README.md
2
+ setup.py
3
+ commitgpt/__init__.py
4
+ commitgpt/ai.py
5
+ commitgpt/cli.py
6
+ commitgpt/git.py
7
+ commitgpt/prompts.py
8
+ commitgpt_nikesh.egg-info/PKG-INFO
9
+ commitgpt_nikesh.egg-info/SOURCES.txt
10
+ commitgpt_nikesh.egg-info/dependency_links.txt
11
+ commitgpt_nikesh.egg-info/entry_points.txt
12
+ commitgpt_nikesh.egg-info/requires.txt
13
+ commitgpt_nikesh.egg-info/top_level.txt
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ cmt = commitgpt.cli:main
@@ -0,0 +1,4 @@
1
+ click
2
+ openai>=1.0.0
3
+ pyperclip
4
+ python-dotenv
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,31 @@
1
+ from setuptools import setup, find_packages
2
+
3
+ setup(
4
+ name="commitgpt-nikesh",
5
+ version="1.0.0",
6
+ packages=find_packages(),
7
+ include_package_data=True,
8
+ install_requires=[
9
+ "click",
10
+ "openai>=1.0.0",
11
+ "pyperclip",
12
+ "python-dotenv",
13
+ ],
14
+ entry_points={
15
+ "console_scripts": [
16
+ "cmt=commitgpt.cli:main",
17
+ ],
18
+ },
19
+ author="Nikesh Sundar",
20
+ author_email="nikeshsundar@users.noreply.github.com",
21
+ description="AI-powered commit messages, standups and PR descriptions from your git diff",
22
+ long_description=open("README.md", encoding="utf-8").read(),
23
+ long_description_content_type="text/markdown",
24
+ url="https://github.com/nikeshsundar/commitgpt",
25
+ classifiers=[
26
+ "Programming Language :: Python :: 3",
27
+ "License :: OSI Approved :: MIT License",
28
+ "Operating System :: OS Independent",
29
+ ],
30
+ python_requires=">=3.9",
31
+ )