hunknote 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.
hunknote-1.0.0/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Avinash Ranganath
4
+ Project: Hunknote
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in all
14
+ copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ SOFTWARE.
@@ -0,0 +1,490 @@
1
+ Metadata-Version: 2.4
2
+ Name: hunknote
3
+ Version: 1.0.0
4
+ Summary: AI-powered git commit message generator with multi-LLM support
5
+ License: MIT
6
+ License-File: LICENSE
7
+ Keywords: git,commit,ai,llm,cli,anthropic,openai,gemini,commit-message,hunknote
8
+ Author: Avinash Ranganath
9
+ Author-email: nash911@gmail.com
10
+ Requires-Python: >=3.12,<4.0
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Environment :: Console
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Programming Language :: Python :: 3.14
20
+ Classifier: Topic :: Software Development :: Quality Assurance
21
+ Classifier: Topic :: Software Development :: Version Control :: Git
22
+ Classifier: Topic :: Utilities
23
+ Requires-Dist: anthropic (>=0.79.0,<0.80.0)
24
+ Requires-Dist: cohere (>=5.20.5,<6.0.0)
25
+ Requires-Dist: google-genai (>=1.63.0,<2.0.0)
26
+ Requires-Dist: groq (>=1.0.0,<2.0.0)
27
+ Requires-Dist: mistralai (>=1.12.2,<2.0.0)
28
+ Requires-Dist: openai (>=2.20.0,<3.0.0)
29
+ Requires-Dist: pydantic (>=2.12.5,<3.0.0)
30
+ Requires-Dist: python-dotenv (>=1.2.1,<2.0.0)
31
+ Requires-Dist: pyyaml (>=6.0.3,<7.0.0)
32
+ Requires-Dist: typer (==0.21.2)
33
+ Project-URL: Documentation, https://github.com/nash911/hunknote#readme
34
+ Project-URL: Homepage, https://github.com/nash911/hunknote
35
+ Project-URL: Repository, https://github.com/nash911/hunknote
36
+ Description-Content-Type: text/markdown
37
+
38
+ # Hunknote
39
+
40
+ A fast, reliable CLI tool that generates high-quality git commit messages from your staged changes using AI.
41
+
42
+ ## Features
43
+
44
+ - **Automatic commit message generation** from staged git changes
45
+ - **Multi-LLM support**: Anthropic, OpenAI, Google Gemini, Mistral, Cohere, Groq, and OpenRouter
46
+ - **Structured output**: Title line + bullet-point body following git best practices
47
+ - **Smart caching**: Reuses generated messages for the same staged changes (no redundant API calls)
48
+ - **Intelligent context**: Distinguishes between new files and modified files for accurate descriptions
49
+ - **Editor integration**: Review and edit generated messages before committing
50
+ - **One-command commits**: Generate and commit in a single step
51
+ - **Configurable ignore patterns**: Exclude lock files, build artifacts, etc. from diff analysis
52
+ - **Debug mode**: Inspect cache metadata, token usage, and file change details
53
+ - **Comprehensive test suite**: 199 unit tests covering all modules
54
+
55
+ ## Installation
56
+
57
+ ### Option 1: Install from PyPI (Recommended)
58
+
59
+ ```bash
60
+ # Using pipx (recommended - installs in isolated environment)
61
+ pipx install hunknote
62
+
63
+ # Or using pip
64
+ pip install hunknote
65
+ ```
66
+
67
+ ### Option 2: Install from Source
68
+
69
+ ```bash
70
+ # Clone the repository
71
+ git clone <repo-url>
72
+ cd ai_commit
73
+
74
+ # Install with Poetry (requires Python 3.12+)
75
+ poetry install
76
+
77
+ # Or install in development mode with test dependencies
78
+ poetry install --with dev
79
+ ```
80
+
81
+ ### Verify Installation
82
+
83
+ ```bash
84
+ # Check that hunknote is available
85
+ hunknote --help
86
+
87
+ # Check git subcommand works
88
+ git hunknote --help
89
+ ```
90
+
91
+ ## Quick Start
92
+
93
+ ```bash
94
+ # Initialize configuration (interactive setup)
95
+ hunknote init
96
+ # This will prompt you to:
97
+ # 1. Select an LLM provider (Anthropic, OpenAI, Google, etc.)
98
+ # 2. Choose a model
99
+ # 3. Enter your API key
100
+
101
+ # Stage your changes
102
+ git add <files>
103
+
104
+ # Generate a commit message
105
+ hunknote
106
+
107
+ # Or generate, edit, and commit in one step
108
+ hunknote -e -c
109
+ ```
110
+
111
+ ## Configuration
112
+
113
+ ### Initial Setup
114
+
115
+ Run the interactive configuration wizard:
116
+
117
+ ```bash
118
+ hunknote init
119
+ ```
120
+
121
+ This creates a global configuration at `~/.hunknote/` with:
122
+ - `config.yaml` - Provider, model, and preference settings
123
+ - `credentials` - Securely stored API keys (read-only permissions)
124
+
125
+ ### Managing Configuration
126
+
127
+ View current configuration:
128
+
129
+ ```bash
130
+ hunknote config show
131
+ ```
132
+
133
+ Change provider or model:
134
+
135
+ ```bash
136
+ # Interactive model selection
137
+ hunknote config set-provider google
138
+
139
+ # Or specify model directly
140
+ hunknote config set-provider anthropic --model claude-sonnet-4-20250514
141
+ ```
142
+
143
+ Update API keys:
144
+
145
+ ```bash
146
+ hunknote config set-key google
147
+ hunknote config set-key anthropic
148
+ ```
149
+
150
+ List available providers and models:
151
+
152
+ ```bash
153
+ hunknote config list-providers
154
+ hunknote config list-models google
155
+ hunknote config list-models # Show all providers and models
156
+ ```
157
+
158
+ ### Manual Configuration
159
+
160
+ Alternatively, you can manually edit `~/.hunknote/config.yaml`:
161
+
162
+ ```yaml
163
+ provider: google
164
+ model: gemini-2.0-flash
165
+ max_tokens: 1500
166
+ temperature: 0.3
167
+ editor: gedit # Optional: preferred editor for -e flag
168
+
169
+ default_ignore: # Optional: patterns to ignore in all repos
170
+ - poetry.lock
171
+ - package-lock.json
172
+ - "*.min.js"
173
+ ```
174
+
175
+ And add API keys to `~/.hunknote/credentials`:
176
+
177
+ ```
178
+ GOOGLE_API_KEY=your_key_here
179
+ ANTHROPIC_API_KEY=your_anthropic_key
180
+ OPENAI_API_KEY=your_openai_key
181
+ ```
182
+
183
+ ### Setting Up API Keys (Alternative Methods)
184
+
185
+ API keys are checked in this order:
186
+ 1. Environment variables (highest priority - useful for CI/CD)
187
+ 2. `~/.hunknote/credentials` file (recommended for local development)
188
+ 3. Project `.env` file (lowest priority)
189
+
190
+ Set via environment variable:
191
+
192
+ ```bash
193
+ # Anthropic
194
+ export ANTHROPIC_API_KEY=your_key_here
195
+
196
+ # OpenAI
197
+ export OPENAI_API_KEY=your_key_here
198
+
199
+ # Google Gemini
200
+ export GOOGLE_API_KEY=your_key_here
201
+
202
+ # Mistral
203
+ export MISTRAL_API_KEY=your_key_here
204
+
205
+ # Cohere
206
+ export COHERE_API_KEY=your_key_here
207
+
208
+ # Groq
209
+ export GROQ_API_KEY=your_key_here
210
+
211
+ # OpenRouter (access to 200+ models)
212
+ export OPENROUTER_API_KEY=your_key_here
213
+ ```
214
+
215
+ Or create a `.env` file in your project root.
216
+
217
+ ### Supported Providers and Models
218
+
219
+ | Provider | Models | API Key Variable |
220
+ |----------|--------|------------------|
221
+ | **Anthropic** | claude-sonnet-4-20250514, claude-3-5-sonnet-latest, claude-3-5-haiku-latest, claude-3-opus-latest | `ANTHROPIC_API_KEY` |
222
+ | **OpenAI** | gpt-4o, gpt-4o-mini, gpt-4-turbo, gpt-3.5-turbo | `OPENAI_API_KEY` |
223
+ | **Google** | gemini-2.5-flash, gemini-2.0-flash, gemini-1.5-pro, gemini-1.5-flash | `GOOGLE_API_KEY` |
224
+ | **Mistral** | mistral-large-latest, mistral-medium-latest, mistral-small-latest, codestral-latest | `MISTRAL_API_KEY` |
225
+ | **Cohere** | command-r-plus, command-r, command | `COHERE_API_KEY` |
226
+ | **Groq** | llama-3.3-70b-versatile, llama-3.1-8b-instant, mixtral-8x7b-32768 | `GROQ_API_KEY` |
227
+ | **OpenRouter** | 200+ models (anthropic/claude-sonnet-4, openai/gpt-4o, meta-llama/llama-3.3-70b-instruct, etc.) | `OPENROUTER_API_KEY` |
228
+
229
+ ## Usage
230
+
231
+ ### Basic Usage
232
+
233
+ Stage your changes and generate a commit message:
234
+
235
+ ```bash
236
+ git add <files>
237
+ hunknote
238
+ ```
239
+
240
+ ### Command Options
241
+
242
+ | Flag | Description |
243
+ |------|-------------|
244
+ | `-e, --edit` | Open the generated message in an editor for manual edits |
245
+ | `-c, --commit` | Automatically commit using the generated message |
246
+ | `-r, --regenerate` | Force regenerate, ignoring cached message |
247
+ | `-d, --debug` | Show full cache metadata (staged files, tokens, diff preview) |
248
+ | `--max-diff-chars` | Maximum characters for staged diff (default: 50000) |
249
+
250
+ ### Ignore Pattern Management
251
+
252
+ Manage which files are excluded from the diff sent to the LLM:
253
+
254
+ ```bash
255
+ # List all ignore patterns
256
+ hunknote ignore list
257
+
258
+ # Add a new pattern
259
+ hunknote ignore add "*.log"
260
+ hunknote ignore add "build/*"
261
+ hunknote ignore add "dist/*"
262
+
263
+ # Remove a pattern
264
+ hunknote ignore remove "*.log"
265
+ ```
266
+
267
+ ### Configuration Commands
268
+
269
+ Manage global configuration stored in `~/.hunknote/`:
270
+
271
+ ```bash
272
+ # View current configuration
273
+ hunknote config show
274
+
275
+ # Set or update API key for a provider
276
+ hunknote config set-key google
277
+ hunknote config set-key anthropic
278
+
279
+ # Change provider and model
280
+ hunknote config set-provider google
281
+ hunknote config set-provider anthropic --model claude-sonnet-4-20250514
282
+
283
+ # List available providers
284
+ hunknote config list-providers
285
+
286
+ # List models for a specific provider
287
+ hunknote config list-models google
288
+
289
+ # List all providers and their models
290
+ hunknote config list-models
291
+ ```
292
+
293
+ ### Examples
294
+
295
+ ```bash
296
+ # Generate commit message (print only, cached for reuse)
297
+ hunknote
298
+
299
+ # Generate and open in editor
300
+ hunknote -e
301
+
302
+ # Generate and commit directly
303
+ hunknote -c
304
+
305
+ # Edit message then commit
306
+ hunknote -e -c
307
+
308
+ # Force regeneration (ignore cache)
309
+ hunknote -r
310
+
311
+ # Debug: view cache metadata and token usage
312
+ hunknote -d
313
+ ```
314
+
315
+ ### Git Subcommand
316
+
317
+ You can also use it as a git subcommand:
318
+
319
+ ```bash
320
+ git hunknote
321
+ git hunknote -e -c
322
+ ```
323
+
324
+ ## How It Works
325
+
326
+ 1. **Collects git context**: branch name, file changes (new vs modified), last 5 commits, and staged diff
327
+ 2. **Computes a hash** of the context to check cache validity
328
+ 3. **Checks cache**: If valid, uses cached message; otherwise calls the configured LLM
329
+ 4. **Parses the response**: Extracts structured JSON (title + bullet points) from LLM response
330
+ 5. **Renders the message**: Formats into standard git commit message format
331
+ 6. **Optionally opens editor** and/or commits
332
+
333
+ ### Intelligent File Change Detection
334
+
335
+ The tool distinguishes between:
336
+ - **New files** (did not exist before this commit)
337
+ - **Modified files** (already existed, now changed)
338
+ - **Deleted files**
339
+ - **Renamed files**
340
+
341
+ This context helps the LLM generate accurate descriptions - for example, it won't say "implement caching" when you're just adding tests for existing caching functionality.
342
+
343
+ ## Caching Behavior
344
+
345
+ The tool caches generated commit messages to avoid redundant API calls:
346
+
347
+ - **Same staged changes** → Uses cached message (no API call)
348
+ - **Different staged changes** → Regenerates automatically
349
+ - **After commit** → Cache is invalidated
350
+ - **Use `-r` flag** → Force regeneration
351
+
352
+ Cache files are stored in `<repo>/.hunknote/`:
353
+ - `hunknote_message.txt` - The cached commit message
354
+ - `hunknote_context_hash.txt` - Hash of the git context
355
+ - `hunknote_metadata.json` - Full metadata (tokens, model, timestamp)
356
+ - `config.yaml` - Repository-specific configuration
357
+
358
+ **Gitignore recommendation:** Add these to your `.gitignore`:
359
+ ```
360
+ # hunknote cache files (but keep config.yaml for shared settings)
361
+ .hunknote/hunknote_*.txt
362
+ .hunknote/hunknote_*.json
363
+ ```
364
+
365
+ ## Repository Configuration
366
+
367
+ Each repository can have its own `.hunknote/config.yaml` file for customization.
368
+ The file is auto-created with defaults on first run.
369
+
370
+ ### Ignore Patterns
371
+
372
+ The `ignore` section lists file patterns to exclude from the diff sent to the LLM.
373
+ This reduces token usage and focuses the commit message on actual code changes.
374
+
375
+ ```yaml
376
+ ignore:
377
+ # Lock files (auto-generated)
378
+ - poetry.lock
379
+ - package-lock.json
380
+ - yarn.lock
381
+ - pnpm-lock.yaml
382
+ - Cargo.lock
383
+ - Gemfile.lock
384
+ - composer.lock
385
+ - go.sum
386
+ # Build artifacts
387
+ - "*.min.js"
388
+ - "*.min.css"
389
+ - "*.map"
390
+ # Binary and generated files
391
+ - "*.pyc"
392
+ - "*.pyo"
393
+ - "*.so"
394
+ - "*.dll"
395
+ - "*.exe"
396
+ # IDE files
397
+ - ".idea/*"
398
+ - ".vscode/*"
399
+ - "*.swp"
400
+ - "*.swo"
401
+ ```
402
+
403
+ You can add custom patterns using glob syntax (e.g., `build/*`, `*.generated.ts`).
404
+
405
+ ## Output Format
406
+
407
+ Generated messages follow git best practices:
408
+
409
+ ```
410
+ Add user authentication feature
411
+
412
+ - Implement login and logout endpoints
413
+ - Add session management middleware
414
+ - Create user model with password hashing
415
+ ```
416
+
417
+ ## Development
418
+
419
+ ### Running Tests
420
+
421
+ The project includes a comprehensive test suite with 199 tests:
422
+
423
+ ```bash
424
+ # Run all tests
425
+ pytest tests/
426
+
427
+ # Run with verbose output
428
+ pytest tests/ -v
429
+
430
+ # Run specific test file
431
+ pytest tests/test_formatters.py
432
+
433
+ # Run specific test
434
+ pytest tests/test_cache.py::TestSaveCache::test_saves_all_files
435
+ ```
436
+
437
+ ### Test Coverage
438
+
439
+ | Module | Tests | Description |
440
+ |--------|-------|-------------|
441
+ | `formatters.py` | 25 | Commit message formatting and validation |
442
+ | `cache.py` | 35 | Caching utilities and metadata |
443
+ | `user_config.py` | 22 | YAML config file management |
444
+ | `git_ctx.py` | 29 | Git context collection and filtering |
445
+ | `llm/base.py` | 27 | JSON parsing, schema validation |
446
+ | `llm/*.py` providers | 23 | All LLM provider classes |
447
+ | `cli.py` | 17 | CLI commands |
448
+ | `config.py` | 22 | Configuration constants |
449
+
450
+ ### Project Structure
451
+
452
+ ```
453
+ hunknote/
454
+ ├── __init__.py
455
+ ├── cli.py # CLI entry point and commands
456
+ ├── config.py # LLM provider configuration
457
+ ├── cache.py # Caching utilities
458
+ ├── formatters.py # Commit message formatting
459
+ ├── git_ctx.py # Git context collection
460
+ ├── user_config.py # Repository config management
461
+ └── llm/
462
+ ├── __init__.py # Provider factory
463
+ ├── base.py # Base classes and prompts
464
+ ├── anthropic_provider.py
465
+ ├── openai_provider.py
466
+ ├── google_provider.py
467
+ ├── mistral_provider.py
468
+ ├── cohere_provider.py
469
+ ├── groq_provider.py
470
+ └── openrouter_provider.py
471
+ ```
472
+
473
+ ## Requirements
474
+
475
+ - Python 3.12+
476
+ - Git
477
+ - API key for at least one supported LLM provider
478
+
479
+ ## Dependencies
480
+
481
+ - `typer` (>=0.21.0) - CLI framework
482
+ - `pydantic` (>=2.5.0) - Data validation
483
+ - `python-dotenv` - Environment variable management
484
+ - `pyyaml` - YAML configuration
485
+ - LLM SDKs: `anthropic`, `openai`, `google-genai`, `mistralai`, `cohere`, `groq`
486
+
487
+ ## License
488
+
489
+ MIT
490
+