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 +22 -0
- hunknote-1.0.0/PKG-INFO +490 -0
- hunknote-1.0.0/README.md +452 -0
- hunknote-1.0.0/hunknote/__init__.py +3 -0
- hunknote-1.0.0/hunknote/__main__.py +7 -0
- hunknote-1.0.0/hunknote/cache.py +334 -0
- hunknote-1.0.0/hunknote/cli.py +828 -0
- hunknote-1.0.0/hunknote/config.py +170 -0
- hunknote-1.0.0/hunknote/formatters.py +79 -0
- hunknote-1.0.0/hunknote/git_ctx.py +352 -0
- hunknote-1.0.0/hunknote/global_config.py +362 -0
- hunknote-1.0.0/hunknote/llm/__init__.py +108 -0
- hunknote-1.0.0/hunknote/llm/anthropic_provider.py +99 -0
- hunknote-1.0.0/hunknote/llm/base.py +213 -0
- hunknote-1.0.0/hunknote/llm/cohere_provider.py +103 -0
- hunknote-1.0.0/hunknote/llm/google_provider.py +198 -0
- hunknote-1.0.0/hunknote/llm/groq_provider.py +103 -0
- hunknote-1.0.0/hunknote/llm/mistral_provider.py +103 -0
- hunknote-1.0.0/hunknote/llm/openai_provider.py +103 -0
- hunknote-1.0.0/hunknote/llm/openrouter_provider.py +118 -0
- hunknote-1.0.0/hunknote/user_config.py +216 -0
- hunknote-1.0.0/pyproject.toml +56 -0
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.
|
hunknote-1.0.0/PKG-INFO
ADDED
|
@@ -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
|
+
|