diffron 0.1.8__tar.gz → 0.1.9__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.
- {diffron-0.1.8 → diffron-0.1.9}/CHANGELOG.md +10 -0
- {diffron-0.1.8/diffron.egg-info → diffron-0.1.9}/PKG-INFO +175 -23
- {diffron-0.1.8 → diffron-0.1.9}/README.md +174 -22
- {diffron-0.1.8 → diffron-0.1.9}/diffron/__init__.py +13 -1
- {diffron-0.1.8 → diffron-0.1.9}/diffron/__init__.pyi +12 -0
- diffron-0.1.9/diffron/agent_detect.py +494 -0
- diffron-0.1.9/diffron/agent_detect.pyi +33 -0
- {diffron-0.1.8 → diffron-0.1.9}/diffron/cli.py +9 -1
- {diffron-0.1.8 → diffron-0.1.9}/diffron/client.py +1 -0
- {diffron-0.1.8 → diffron-0.1.9}/diffron/client.pyi +1 -0
- {diffron-0.1.8 → diffron-0.1.9/diffron}/hooks/prepare-commit-msg-global.py +18 -0
- {diffron-0.1.8 → diffron-0.1.9/diffron}/hooks/prepare-commit-msg.py +18 -0
- {diffron-0.1.8 → diffron-0.1.9}/diffron/lemonade.py +4 -3
- {diffron-0.1.8 → diffron-0.1.9}/diffron/models.py +97 -24
- {diffron-0.1.8 → diffron-0.1.9/diffron.egg-info}/PKG-INFO +175 -23
- {diffron-0.1.8 → diffron-0.1.9}/diffron.egg-info/SOURCES.txt +2 -0
- {diffron-0.1.8 → diffron-0.1.9}/docs/HOOKS.md +73 -4
- {diffron-0.1.8/diffron → diffron-0.1.9}/hooks/prepare-commit-msg-global.py +18 -0
- {diffron-0.1.8/diffron → diffron-0.1.9}/hooks/prepare-commit-msg.py +18 -0
- {diffron-0.1.8 → diffron-0.1.9}/pyproject.toml +1 -1
- {diffron-0.1.8 → diffron-0.1.9}/LICENSE +0 -0
- {diffron-0.1.8 → diffron-0.1.9}/MANIFEST.in +0 -0
- {diffron-0.1.8 → diffron-0.1.9}/diffron/__main__.py +0 -0
- {diffron-0.1.8 → diffron-0.1.9}/diffron/cli.pyi +0 -0
- {diffron-0.1.8 → diffron-0.1.9}/diffron/commit_gen.py +0 -0
- {diffron-0.1.8 → diffron-0.1.9}/diffron/commit_gen.pyi +0 -0
- {diffron-0.1.8 → diffron-0.1.9}/diffron/git_hooks.py +0 -0
- {diffron-0.1.8 → diffron-0.1.9}/diffron/git_hooks.pyi +0 -0
- {diffron-0.1.8 → diffron-0.1.9}/diffron/hooks/aipr.py +0 -0
- {diffron-0.1.8 → diffron-0.1.9}/diffron/hooks/prepare-commit-msg +0 -0
- {diffron-0.1.8 → diffron-0.1.9}/diffron/lemonade.pyi +0 -0
- {diffron-0.1.8 → diffron-0.1.9}/diffron/models.pyi +0 -0
- {diffron-0.1.8 → diffron-0.1.9}/diffron/pr_gen.py +0 -0
- {diffron-0.1.8 → diffron-0.1.9}/diffron/pr_gen.pyi +0 -0
- {diffron-0.1.8 → diffron-0.1.9}/diffron/py.typed +0 -0
- {diffron-0.1.8 → diffron-0.1.9}/diffron/utils.py +0 -0
- {diffron-0.1.8 → diffron-0.1.9}/diffron/utils.pyi +0 -0
- {diffron-0.1.8 → diffron-0.1.9}/diffron.egg-info/dependency_links.txt +0 -0
- {diffron-0.1.8 → diffron-0.1.9}/diffron.egg-info/entry_points.txt +0 -0
- {diffron-0.1.8 → diffron-0.1.9}/diffron.egg-info/requires.txt +0 -0
- {diffron-0.1.8 → diffron-0.1.9}/diffron.egg-info/top_level.txt +0 -0
- {diffron-0.1.8 → diffron-0.1.9}/docs/LEMONADE_PORT_VERIFICATION_FIX.md +0 -0
- {diffron-0.1.8 → diffron-0.1.9}/docs/LEMONADE_UNRESPONSIVE_FIX.md +0 -0
- {diffron-0.1.8 → diffron-0.1.9}/docs/MODEL_NAME_CASE_FIX.md +0 -0
- {diffron-0.1.8 → diffron-0.1.9}/docs/SETUP.md +0 -0
- {diffron-0.1.8 → diffron-0.1.9}/docs/USAGE.md +0 -0
- {diffron-0.1.8 → diffron-0.1.9}/hooks/aipr.py +0 -0
- {diffron-0.1.8 → diffron-0.1.9}/requirements.txt +0 -0
- {diffron-0.1.8 → diffron-0.1.9}/setup.cfg +0 -0
- {diffron-0.1.8 → diffron-0.1.9}/setup.py +0 -0
|
@@ -10,6 +10,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
10
10
|
## [Unreleased]
|
|
11
11
|
|
|
12
12
|
### Added
|
|
13
|
+
- **AI Agent Detection** — Diffron now automatically skips message generation when an AI coding agent is detected
|
|
14
|
+
- Predefined registry of 35+ known AI agents (CLI, GUI, Cloud, Agent frameworks)
|
|
15
|
+
- Environment variable scanning: detects env vars from all registered agents
|
|
16
|
+
- Git config detection: checks user.name/email for AI agent patterns
|
|
17
|
+
- Commit message quality: skips if message already follows Conventional Commits format
|
|
18
|
+
- User-configurable: `DIFFRON_SKIP_PATTERNS` env var and `git config diffron.skip-patterns`
|
|
19
|
+
- New functions: `is_ai_agent_commit()`, `is_well_formed_commit()`, `list_known_agents()`, `list_agent_names()`, `get_agents_by_type()`
|
|
20
|
+
- `diffron status` now shows AI agent detection status
|
|
21
|
+
- New `agent_detect.py` module with `agent_detect.pyi` type stub
|
|
22
|
+
|
|
13
23
|
**Robust Model Reload Fix** — Properly unload and reload Lemonade model using SDK's native methods when unresponsive
|
|
14
24
|
- Fixed `'NoneType' object is not subscriptable` error by using `_LemonadeSDKClient` for server operations
|
|
15
25
|
- Uses `sdk_client.unload_model()` followed by `sdk_client.load_model(model_name=self.model)` for true server restart
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: diffron
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.9
|
|
4
4
|
Summary: Git commit message and PR description generator using Lemonade
|
|
5
5
|
Home-page: https://github.com/diffron/diffron
|
|
6
6
|
Author: Diffron Contributors
|
|
@@ -47,10 +47,10 @@ Git commit message and PR description generator using AMD Lemonade via lemonade-
|
|
|
47
47
|
|
|
48
48
|
**Diffron is a production-ready reference implementation of the lemonade-python-sdk — submitted to the AMD Lemonade Developer Challenge 2026.**
|
|
49
49
|
|
|
50
|
-

|
|
51
51
|

|
|
52
52
|

|
|
53
|
-

|
|
53
|
+

|
|
54
54
|
|
|
55
55
|
---
|
|
56
56
|
|
|
@@ -59,9 +59,10 @@ Git commit message and PR description generator using AMD Lemonade via lemonade-
|
|
|
59
59
|
- 🤖 **Auto Commit Messages** - Generates Conventional Commits format messages from your staged changes
|
|
60
60
|
- 📝 **PR Descriptions** - Creates detailed PR titles and descriptions from branch diffs
|
|
61
61
|
- 🔌 **Lemonade Integration** - Works with your local Lemonade LLM server (no cloud required)
|
|
62
|
-
- 🪟 **
|
|
62
|
+
- 🪟 **Cross-Platform** - Works on Windows, Linux, and macOS with GitHub Desktop 3.5.5+ support
|
|
63
63
|
- ⚡ **Auto-Detection** - Automatically finds your running Lemonade instance
|
|
64
64
|
- 🎯 **Curated Models** - Easy model selection with recommended models for different tasks
|
|
65
|
+
- 🧠 **AI-Aware** - Automatically skips when AI coding agents (Claude, Copilot, Cursor, Aider, MiMo, Kilo, Qwen, etc.) are making commits
|
|
65
66
|
|
|
66
67
|
---
|
|
67
68
|
|
|
@@ -91,16 +92,30 @@ pip install lemonade-sdk
|
|
|
91
92
|
### 3. Configure Environment
|
|
92
93
|
|
|
93
94
|
**Set Lemonade Server URL (Permanent):**
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
95
|
+
|
|
96
|
+
Windows:
|
|
97
|
+
```cmd
|
|
98
|
+
setx LEMONADE_SERVER_URL http://localhost:8020
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Linux/macOS:
|
|
102
|
+
```bash
|
|
103
|
+
echo 'export LEMONADE_SERVER_URL="http://localhost:8020"' >> ~/.bashrc
|
|
104
|
+
source ~/.bashrc
|
|
105
|
+
```
|
|
98
106
|
|
|
99
107
|
**Or Temporary (current session):**
|
|
108
|
+
|
|
109
|
+
Windows:
|
|
100
110
|
```cmd
|
|
101
111
|
set LEMONADE_SERVER_URL=http://localhost:8020
|
|
102
112
|
```
|
|
103
113
|
|
|
114
|
+
Linux/macOS:
|
|
115
|
+
```bash
|
|
116
|
+
export LEMONADE_SERVER_URL=http://localhost:8020
|
|
117
|
+
```
|
|
118
|
+
|
|
104
119
|
### 4. Install Diffron
|
|
105
120
|
|
|
106
121
|
```bash
|
|
@@ -143,13 +158,15 @@ print(f"Default: {default.name}")
|
|
|
143
158
|
|
|
144
159
|
**Or manually via environment variable:**
|
|
145
160
|
|
|
161
|
+
Windows:
|
|
146
162
|
```cmd
|
|
147
|
-
|
|
148
|
-
|
|
163
|
+
setx DIFFRON_MODEL "qwen3.5-0.8b-gguf"
|
|
164
|
+
```
|
|
149
165
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
166
|
+
Linux/macOS:
|
|
167
|
+
```bash
|
|
168
|
+
echo 'export DIFFRON_MODEL="qwen3.5-0.8b-gguf"' >> ~/.bashrc
|
|
169
|
+
source ~/.bashrc
|
|
153
170
|
```
|
|
154
171
|
|
|
155
172
|
### 5. Install Git Hooks
|
|
@@ -206,8 +223,11 @@ python -c "from diffron.git_hooks import install_hooks; install_hooks(global_ins
|
|
|
206
223
|
# Generate PR description
|
|
207
224
|
python -c "from diffron import generate_pr_description; pr = generate_pr_description(); print(pr.format_output())"
|
|
208
225
|
|
|
209
|
-
# Check status
|
|
210
|
-
|
|
226
|
+
# Check status (Lemonade, hooks, AI agent detection)
|
|
227
|
+
diffron status
|
|
228
|
+
|
|
229
|
+
# Check if AI agent is detected
|
|
230
|
+
python -c "from diffron import is_ai_agent_commit; print('AI agent:', is_ai_agent_commit())"
|
|
211
231
|
```
|
|
212
232
|
|
|
213
233
|
### Python API
|
|
@@ -239,6 +259,102 @@ client.install_hooks(global_install=True)
|
|
|
239
259
|
4. Click "Commit to main"
|
|
240
260
|
5. **Diffron replaces** your message with AI-generated message
|
|
241
261
|
|
|
262
|
+
### AI Agent Detection
|
|
263
|
+
|
|
264
|
+
Diffron automatically detects when an AI coding agent (Claude, Copilot, Cursor, Aider, Codex, Kilo, Mimo, Hermes, OpenCode, FreeBuff, etc.) is making a commit and **skips** message generation — the agent already produces good messages.
|
|
265
|
+
|
|
266
|
+
**Check detection status:**
|
|
267
|
+
|
|
268
|
+
```bash
|
|
269
|
+
diffron status
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
Output:
|
|
273
|
+
```
|
|
274
|
+
AI Agent Detection:
|
|
275
|
+
✓ AI agent detected — Diffron will skip this commit
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
**How it works (3 layers):**
|
|
279
|
+
|
|
280
|
+
1. **Environment variables** — Scans all env vars for AI agent keywords (`CLAUDE`, `COPILOT`, `CURSOR`, `AIDER`, `CODEX`, `OPENAI`, `AGENT`, `BOT`, etc.)
|
|
281
|
+
2. **Git config** — Checks `user.name` and `user.email` for AI patterns (e.g., "Claude", "Copilot", "ai@anthropic.com")
|
|
282
|
+
3. **Message quality** — If the commit message already follows Conventional Commits format (`feat:`, `fix:`, etc.), Diffron skips
|
|
283
|
+
|
|
284
|
+
**Add custom detection patterns:**
|
|
285
|
+
|
|
286
|
+
Windows:
|
|
287
|
+
```cmd
|
|
288
|
+
set DIFFRON_SKIP_PATTERNS=MY_AI_TOOL,DEV_BOT
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
Linux/macOS:
|
|
292
|
+
```bash
|
|
293
|
+
export DIFFRON_SKIP_PATTERNS=MY_AI_TOOL,DEV_BOT
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
**Or via git config:**
|
|
297
|
+
|
|
298
|
+
```bash
|
|
299
|
+
git config diffron.skip-patterns "MY_AI_TOOL,DEV_BOT"
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
**Test it manually:**
|
|
303
|
+
|
|
304
|
+
Windows:
|
|
305
|
+
```cmd
|
|
306
|
+
set CLAUDE_CODE_SESSION=1
|
|
307
|
+
diffron status
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
Linux/macOS:
|
|
311
|
+
```bash
|
|
312
|
+
CLAUDE_CODE_SESSION=1 diffron status
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
**Python API:**
|
|
316
|
+
|
|
317
|
+
```python
|
|
318
|
+
from diffron import (
|
|
319
|
+
is_ai_agent_commit,
|
|
320
|
+
is_well_formed_commit,
|
|
321
|
+
list_known_agents,
|
|
322
|
+
list_agent_names,
|
|
323
|
+
get_agents_by_type,
|
|
324
|
+
)
|
|
325
|
+
|
|
326
|
+
# Check if AI agent is detected
|
|
327
|
+
if is_ai_agent_commit():
|
|
328
|
+
print("Skipping — AI agent detected")
|
|
329
|
+
|
|
330
|
+
# Check if message is already good
|
|
331
|
+
if is_well_formed_commit("feat: add new feature"):
|
|
332
|
+
print("Skipping — message already follows Conventional Commits")
|
|
333
|
+
|
|
334
|
+
# List all known AI agents
|
|
335
|
+
agents = list_known_agents()
|
|
336
|
+
for agent in agents:
|
|
337
|
+
print(f"{agent['name']} ({agent['type']})")
|
|
338
|
+
|
|
339
|
+
# List just the names
|
|
340
|
+
print(list_agent_names())
|
|
341
|
+
|
|
342
|
+
# Get agents by type
|
|
343
|
+
cli_agents = get_agents_by_type("cli") # CLI coding agents
|
|
344
|
+
gui_agents = get_agents_by_type("gui") # IDE/GUI plugins
|
|
345
|
+
cloud_agents = get_agents_by_type("cloud") # Cloud environments
|
|
346
|
+
agent_frameworks = get_agents_by_type("agent") # Agent frameworks
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
**Known agents in the registry:**
|
|
350
|
+
|
|
351
|
+
| Category | Agents |
|
|
352
|
+
|----------|--------|
|
|
353
|
+
| **CLI** | Claude Code, Copilot CLI, Aider, Codex CLI, Amazon Q, Cline, Windsurf, Continue.dev, Tabnine, Cody, Augment, MarsCode, PearAI, Void, Supermaven, MiMo Code, Kilo Code, Hermes, FreeBuff, OpenCode, Qwen Coder |
|
|
354
|
+
| **GUI** | Cursor, Windsurf IDE, Copilot (VS Code), Cline (VS Code), Continue.dev (VS Code), Tabnine, Amazon Q (VS Code), Cody (VS Code), MarsCode, JetBrains AI |
|
|
355
|
+
| **Cloud** | GitHub Codespaces, GitPod, Replit |
|
|
356
|
+
| **Agent** | Devin, SWE-agent, OpenHands, AutoCodeRover, Mintlify |
|
|
357
|
+
|
|
242
358
|
---
|
|
243
359
|
|
|
244
360
|
## Configuration
|
|
@@ -250,6 +366,7 @@ client.install_hooks(global_install=True)
|
|
|
250
366
|
| `LEMONADE_SERVER_URL` | `http://localhost:8020` | Lemonade server URL |
|
|
251
367
|
| `DIFFRON_MODEL` | `qwen2.5-it-3b-FLM` | Model name to use |
|
|
252
368
|
| `DIFFRON_MAX_DIFF_CHARS` | `4000` | Max diff characters |
|
|
369
|
+
| `DIFFRON_SKIP_PATTERNS` | *(empty)* | Comma-separated env var names to check for AI agent detection |
|
|
253
370
|
|
|
254
371
|
### Curated Models
|
|
255
372
|
|
|
@@ -270,11 +387,21 @@ diffron-setup-model --model qwen3.5-0.8b-gguf
|
|
|
270
387
|
|
|
271
388
|
# List available models
|
|
272
389
|
diffron-setup-model --list
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
Or manually:
|
|
273
393
|
|
|
274
|
-
|
|
394
|
+
Windows:
|
|
395
|
+
```cmd
|
|
275
396
|
setx DIFFRON_MODEL "qwen3.5-0.8b-gguf"
|
|
276
397
|
```
|
|
277
398
|
|
|
399
|
+
Linux/macOS:
|
|
400
|
+
```bash
|
|
401
|
+
echo 'export DIFFRON_MODEL="qwen3.5-0.8b-gguf"' >> ~/.bashrc
|
|
402
|
+
source ~/.bashrc
|
|
403
|
+
```
|
|
404
|
+
|
|
278
405
|
### Python API
|
|
279
406
|
|
|
280
407
|
```python
|
|
@@ -335,22 +462,29 @@ if config:
|
|
|
335
462
|
└─────────────────────────────────────────────────────────┘
|
|
336
463
|
↓
|
|
337
464
|
┌─────────────────────────────────────────────────────────┐
|
|
338
|
-
│ 3. Hook
|
|
465
|
+
│ 3. Hook checks for skip conditions: │
|
|
466
|
+
│ - Merge / rebase / amend → skip │
|
|
467
|
+
│ - AI agent detected → skip │
|
|
468
|
+
│ - Message already well-formed → skip │
|
|
339
469
|
└─────────────────────────────────────────────────────────┘
|
|
340
470
|
↓
|
|
341
471
|
┌─────────────────────────────────────────────────────────┐
|
|
342
|
-
│ 4. Hook
|
|
472
|
+
│ 4. Hook reads staged diff: git diff --cached │
|
|
473
|
+
└─────────────────────────────────────────────────────────┘
|
|
474
|
+
↓
|
|
475
|
+
┌─────────────────────────────────────────────────────────┐
|
|
476
|
+
│ 5. Hook calls Lemonade API │
|
|
343
477
|
│ - URL: http://localhost:8020/api/v1 │
|
|
344
478
|
│ - Model: qwen3.5-0.8b-gguf (default) │
|
|
345
479
|
└─────────────────────────────────────────────────────────┘
|
|
346
480
|
↓
|
|
347
481
|
┌─────────────────────────────────────────────────────────┐
|
|
348
|
-
│
|
|
482
|
+
│ 6. AI generates Conventional Commit message │
|
|
349
483
|
│ - "feat: add user authentication module" │
|
|
350
484
|
└─────────────────────────────────────────────────────────┘
|
|
351
485
|
↓
|
|
352
486
|
┌─────────────────────────────────────────────────────────┐
|
|
353
|
-
│
|
|
487
|
+
│ 7. Git opens editor with generated message │
|
|
354
488
|
│ - User can review/modify before saving │
|
|
355
489
|
└─────────────────────────────────────────────────────────┘
|
|
356
490
|
```
|
|
@@ -366,7 +500,8 @@ if config:
|
|
|
366
500
|
lemonade serve qwen3.5-0.8b-gguf
|
|
367
501
|
|
|
368
502
|
# Verify URL
|
|
369
|
-
echo
|
|
503
|
+
echo $LEMONADE_SERVER_URL # Linux/macOS
|
|
504
|
+
echo %LEMONADE_SERVER_URL% # Windows
|
|
370
505
|
```
|
|
371
506
|
|
|
372
507
|
### Hooks Not Working
|
|
@@ -399,9 +534,11 @@ diffron-setup-model --list
|
|
|
399
534
|
**Cause:** `DIFFRON_MODEL` environment variable overrides the default.
|
|
400
535
|
|
|
401
536
|
**Solution:**
|
|
537
|
+
|
|
402
538
|
```bash
|
|
403
539
|
# Check current value
|
|
404
|
-
echo
|
|
540
|
+
echo $DIFFRON_MODEL # Linux/macOS
|
|
541
|
+
echo %DIFFRON_MODEL% # Windows
|
|
405
542
|
|
|
406
543
|
# Reset to recommended
|
|
407
544
|
diffron-setup-model --model qwen3.5-0.8b-gguf
|
|
@@ -412,6 +549,21 @@ diffron-setup-model
|
|
|
412
549
|
|
|
413
550
|
See [docs/SETUP.md](docs/SETUP.md) for complete troubleshooting guide.
|
|
414
551
|
|
|
552
|
+
### Diffron Not Generating Messages (AI Agent Detected)
|
|
553
|
+
|
|
554
|
+
**Symptom:** `git commit` works but Diffron doesn't generate a message.
|
|
555
|
+
|
|
556
|
+
**Cause:** An AI agent environment variable is detected (e.g., `CLAUDE_CODE_SESSION`, `CURSOR_SESSION_ID`).
|
|
557
|
+
|
|
558
|
+
**Solution:**
|
|
559
|
+
```bash
|
|
560
|
+
# Check what's being detected
|
|
561
|
+
diffron status
|
|
562
|
+
|
|
563
|
+
# If false positive, add the env var to exclude list
|
|
564
|
+
# (or unset the triggering env var)
|
|
565
|
+
```
|
|
566
|
+
|
|
415
567
|
---
|
|
416
568
|
|
|
417
569
|
## License
|
|
@@ -454,4 +606,4 @@ pytest tests/
|
|
|
454
606
|
|
|
455
607
|
---
|
|
456
608
|
|
|
457
|
-
*Version: 0.1.
|
|
609
|
+
*Version: 0.1.9 | Last updated: 2026-07-11*
|
|
@@ -4,10 +4,10 @@ Git commit message and PR description generator using AMD Lemonade via lemonade-
|
|
|
4
4
|
|
|
5
5
|
**Diffron is a production-ready reference implementation of the lemonade-python-sdk — submitted to the AMD Lemonade Developer Challenge 2026.**
|
|
6
6
|
|
|
7
|
-

|
|
8
8
|

|
|
9
9
|

|
|
10
|
-

|
|
10
|
+

|
|
11
11
|
|
|
12
12
|
---
|
|
13
13
|
|
|
@@ -16,9 +16,10 @@ Git commit message and PR description generator using AMD Lemonade via lemonade-
|
|
|
16
16
|
- 🤖 **Auto Commit Messages** - Generates Conventional Commits format messages from your staged changes
|
|
17
17
|
- 📝 **PR Descriptions** - Creates detailed PR titles and descriptions from branch diffs
|
|
18
18
|
- 🔌 **Lemonade Integration** - Works with your local Lemonade LLM server (no cloud required)
|
|
19
|
-
- 🪟 **
|
|
19
|
+
- 🪟 **Cross-Platform** - Works on Windows, Linux, and macOS with GitHub Desktop 3.5.5+ support
|
|
20
20
|
- ⚡ **Auto-Detection** - Automatically finds your running Lemonade instance
|
|
21
21
|
- 🎯 **Curated Models** - Easy model selection with recommended models for different tasks
|
|
22
|
+
- 🧠 **AI-Aware** - Automatically skips when AI coding agents (Claude, Copilot, Cursor, Aider, MiMo, Kilo, Qwen, etc.) are making commits
|
|
22
23
|
|
|
23
24
|
---
|
|
24
25
|
|
|
@@ -48,16 +49,30 @@ pip install lemonade-sdk
|
|
|
48
49
|
### 3. Configure Environment
|
|
49
50
|
|
|
50
51
|
**Set Lemonade Server URL (Permanent):**
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
52
|
+
|
|
53
|
+
Windows:
|
|
54
|
+
```cmd
|
|
55
|
+
setx LEMONADE_SERVER_URL http://localhost:8020
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Linux/macOS:
|
|
59
|
+
```bash
|
|
60
|
+
echo 'export LEMONADE_SERVER_URL="http://localhost:8020"' >> ~/.bashrc
|
|
61
|
+
source ~/.bashrc
|
|
62
|
+
```
|
|
55
63
|
|
|
56
64
|
**Or Temporary (current session):**
|
|
65
|
+
|
|
66
|
+
Windows:
|
|
57
67
|
```cmd
|
|
58
68
|
set LEMONADE_SERVER_URL=http://localhost:8020
|
|
59
69
|
```
|
|
60
70
|
|
|
71
|
+
Linux/macOS:
|
|
72
|
+
```bash
|
|
73
|
+
export LEMONADE_SERVER_URL=http://localhost:8020
|
|
74
|
+
```
|
|
75
|
+
|
|
61
76
|
### 4. Install Diffron
|
|
62
77
|
|
|
63
78
|
```bash
|
|
@@ -100,13 +115,15 @@ print(f"Default: {default.name}")
|
|
|
100
115
|
|
|
101
116
|
**Or manually via environment variable:**
|
|
102
117
|
|
|
118
|
+
Windows:
|
|
103
119
|
```cmd
|
|
104
|
-
|
|
105
|
-
|
|
120
|
+
setx DIFFRON_MODEL "qwen3.5-0.8b-gguf"
|
|
121
|
+
```
|
|
106
122
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
123
|
+
Linux/macOS:
|
|
124
|
+
```bash
|
|
125
|
+
echo 'export DIFFRON_MODEL="qwen3.5-0.8b-gguf"' >> ~/.bashrc
|
|
126
|
+
source ~/.bashrc
|
|
110
127
|
```
|
|
111
128
|
|
|
112
129
|
### 5. Install Git Hooks
|
|
@@ -163,8 +180,11 @@ python -c "from diffron.git_hooks import install_hooks; install_hooks(global_ins
|
|
|
163
180
|
# Generate PR description
|
|
164
181
|
python -c "from diffron import generate_pr_description; pr = generate_pr_description(); print(pr.format_output())"
|
|
165
182
|
|
|
166
|
-
# Check status
|
|
167
|
-
|
|
183
|
+
# Check status (Lemonade, hooks, AI agent detection)
|
|
184
|
+
diffron status
|
|
185
|
+
|
|
186
|
+
# Check if AI agent is detected
|
|
187
|
+
python -c "from diffron import is_ai_agent_commit; print('AI agent:', is_ai_agent_commit())"
|
|
168
188
|
```
|
|
169
189
|
|
|
170
190
|
### Python API
|
|
@@ -196,6 +216,102 @@ client.install_hooks(global_install=True)
|
|
|
196
216
|
4. Click "Commit to main"
|
|
197
217
|
5. **Diffron replaces** your message with AI-generated message
|
|
198
218
|
|
|
219
|
+
### AI Agent Detection
|
|
220
|
+
|
|
221
|
+
Diffron automatically detects when an AI coding agent (Claude, Copilot, Cursor, Aider, Codex, Kilo, Mimo, Hermes, OpenCode, FreeBuff, etc.) is making a commit and **skips** message generation — the agent already produces good messages.
|
|
222
|
+
|
|
223
|
+
**Check detection status:**
|
|
224
|
+
|
|
225
|
+
```bash
|
|
226
|
+
diffron status
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
Output:
|
|
230
|
+
```
|
|
231
|
+
AI Agent Detection:
|
|
232
|
+
✓ AI agent detected — Diffron will skip this commit
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
**How it works (3 layers):**
|
|
236
|
+
|
|
237
|
+
1. **Environment variables** — Scans all env vars for AI agent keywords (`CLAUDE`, `COPILOT`, `CURSOR`, `AIDER`, `CODEX`, `OPENAI`, `AGENT`, `BOT`, etc.)
|
|
238
|
+
2. **Git config** — Checks `user.name` and `user.email` for AI patterns (e.g., "Claude", "Copilot", "ai@anthropic.com")
|
|
239
|
+
3. **Message quality** — If the commit message already follows Conventional Commits format (`feat:`, `fix:`, etc.), Diffron skips
|
|
240
|
+
|
|
241
|
+
**Add custom detection patterns:**
|
|
242
|
+
|
|
243
|
+
Windows:
|
|
244
|
+
```cmd
|
|
245
|
+
set DIFFRON_SKIP_PATTERNS=MY_AI_TOOL,DEV_BOT
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
Linux/macOS:
|
|
249
|
+
```bash
|
|
250
|
+
export DIFFRON_SKIP_PATTERNS=MY_AI_TOOL,DEV_BOT
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
**Or via git config:**
|
|
254
|
+
|
|
255
|
+
```bash
|
|
256
|
+
git config diffron.skip-patterns "MY_AI_TOOL,DEV_BOT"
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
**Test it manually:**
|
|
260
|
+
|
|
261
|
+
Windows:
|
|
262
|
+
```cmd
|
|
263
|
+
set CLAUDE_CODE_SESSION=1
|
|
264
|
+
diffron status
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
Linux/macOS:
|
|
268
|
+
```bash
|
|
269
|
+
CLAUDE_CODE_SESSION=1 diffron status
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
**Python API:**
|
|
273
|
+
|
|
274
|
+
```python
|
|
275
|
+
from diffron import (
|
|
276
|
+
is_ai_agent_commit,
|
|
277
|
+
is_well_formed_commit,
|
|
278
|
+
list_known_agents,
|
|
279
|
+
list_agent_names,
|
|
280
|
+
get_agents_by_type,
|
|
281
|
+
)
|
|
282
|
+
|
|
283
|
+
# Check if AI agent is detected
|
|
284
|
+
if is_ai_agent_commit():
|
|
285
|
+
print("Skipping — AI agent detected")
|
|
286
|
+
|
|
287
|
+
# Check if message is already good
|
|
288
|
+
if is_well_formed_commit("feat: add new feature"):
|
|
289
|
+
print("Skipping — message already follows Conventional Commits")
|
|
290
|
+
|
|
291
|
+
# List all known AI agents
|
|
292
|
+
agents = list_known_agents()
|
|
293
|
+
for agent in agents:
|
|
294
|
+
print(f"{agent['name']} ({agent['type']})")
|
|
295
|
+
|
|
296
|
+
# List just the names
|
|
297
|
+
print(list_agent_names())
|
|
298
|
+
|
|
299
|
+
# Get agents by type
|
|
300
|
+
cli_agents = get_agents_by_type("cli") # CLI coding agents
|
|
301
|
+
gui_agents = get_agents_by_type("gui") # IDE/GUI plugins
|
|
302
|
+
cloud_agents = get_agents_by_type("cloud") # Cloud environments
|
|
303
|
+
agent_frameworks = get_agents_by_type("agent") # Agent frameworks
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
**Known agents in the registry:**
|
|
307
|
+
|
|
308
|
+
| Category | Agents |
|
|
309
|
+
|----------|--------|
|
|
310
|
+
| **CLI** | Claude Code, Copilot CLI, Aider, Codex CLI, Amazon Q, Cline, Windsurf, Continue.dev, Tabnine, Cody, Augment, MarsCode, PearAI, Void, Supermaven, MiMo Code, Kilo Code, Hermes, FreeBuff, OpenCode, Qwen Coder |
|
|
311
|
+
| **GUI** | Cursor, Windsurf IDE, Copilot (VS Code), Cline (VS Code), Continue.dev (VS Code), Tabnine, Amazon Q (VS Code), Cody (VS Code), MarsCode, JetBrains AI |
|
|
312
|
+
| **Cloud** | GitHub Codespaces, GitPod, Replit |
|
|
313
|
+
| **Agent** | Devin, SWE-agent, OpenHands, AutoCodeRover, Mintlify |
|
|
314
|
+
|
|
199
315
|
---
|
|
200
316
|
|
|
201
317
|
## Configuration
|
|
@@ -207,6 +323,7 @@ client.install_hooks(global_install=True)
|
|
|
207
323
|
| `LEMONADE_SERVER_URL` | `http://localhost:8020` | Lemonade server URL |
|
|
208
324
|
| `DIFFRON_MODEL` | `qwen2.5-it-3b-FLM` | Model name to use |
|
|
209
325
|
| `DIFFRON_MAX_DIFF_CHARS` | `4000` | Max diff characters |
|
|
326
|
+
| `DIFFRON_SKIP_PATTERNS` | *(empty)* | Comma-separated env var names to check for AI agent detection |
|
|
210
327
|
|
|
211
328
|
### Curated Models
|
|
212
329
|
|
|
@@ -227,11 +344,21 @@ diffron-setup-model --model qwen3.5-0.8b-gguf
|
|
|
227
344
|
|
|
228
345
|
# List available models
|
|
229
346
|
diffron-setup-model --list
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
Or manually:
|
|
230
350
|
|
|
231
|
-
|
|
351
|
+
Windows:
|
|
352
|
+
```cmd
|
|
232
353
|
setx DIFFRON_MODEL "qwen3.5-0.8b-gguf"
|
|
233
354
|
```
|
|
234
355
|
|
|
356
|
+
Linux/macOS:
|
|
357
|
+
```bash
|
|
358
|
+
echo 'export DIFFRON_MODEL="qwen3.5-0.8b-gguf"' >> ~/.bashrc
|
|
359
|
+
source ~/.bashrc
|
|
360
|
+
```
|
|
361
|
+
|
|
235
362
|
### Python API
|
|
236
363
|
|
|
237
364
|
```python
|
|
@@ -292,22 +419,29 @@ if config:
|
|
|
292
419
|
└─────────────────────────────────────────────────────────┘
|
|
293
420
|
↓
|
|
294
421
|
┌─────────────────────────────────────────────────────────┐
|
|
295
|
-
│ 3. Hook
|
|
422
|
+
│ 3. Hook checks for skip conditions: │
|
|
423
|
+
│ - Merge / rebase / amend → skip │
|
|
424
|
+
│ - AI agent detected → skip │
|
|
425
|
+
│ - Message already well-formed → skip │
|
|
296
426
|
└─────────────────────────────────────────────────────────┘
|
|
297
427
|
↓
|
|
298
428
|
┌─────────────────────────────────────────────────────────┐
|
|
299
|
-
│ 4. Hook
|
|
429
|
+
│ 4. Hook reads staged diff: git diff --cached │
|
|
430
|
+
└─────────────────────────────────────────────────────────┘
|
|
431
|
+
↓
|
|
432
|
+
┌─────────────────────────────────────────────────────────┐
|
|
433
|
+
│ 5. Hook calls Lemonade API │
|
|
300
434
|
│ - URL: http://localhost:8020/api/v1 │
|
|
301
435
|
│ - Model: qwen3.5-0.8b-gguf (default) │
|
|
302
436
|
└─────────────────────────────────────────────────────────┘
|
|
303
437
|
↓
|
|
304
438
|
┌─────────────────────────────────────────────────────────┐
|
|
305
|
-
│
|
|
439
|
+
│ 6. AI generates Conventional Commit message │
|
|
306
440
|
│ - "feat: add user authentication module" │
|
|
307
441
|
└─────────────────────────────────────────────────────────┘
|
|
308
442
|
↓
|
|
309
443
|
┌─────────────────────────────────────────────────────────┐
|
|
310
|
-
│
|
|
444
|
+
│ 7. Git opens editor with generated message │
|
|
311
445
|
│ - User can review/modify before saving │
|
|
312
446
|
└─────────────────────────────────────────────────────────┘
|
|
313
447
|
```
|
|
@@ -323,7 +457,8 @@ if config:
|
|
|
323
457
|
lemonade serve qwen3.5-0.8b-gguf
|
|
324
458
|
|
|
325
459
|
# Verify URL
|
|
326
|
-
echo
|
|
460
|
+
echo $LEMONADE_SERVER_URL # Linux/macOS
|
|
461
|
+
echo %LEMONADE_SERVER_URL% # Windows
|
|
327
462
|
```
|
|
328
463
|
|
|
329
464
|
### Hooks Not Working
|
|
@@ -356,9 +491,11 @@ diffron-setup-model --list
|
|
|
356
491
|
**Cause:** `DIFFRON_MODEL` environment variable overrides the default.
|
|
357
492
|
|
|
358
493
|
**Solution:**
|
|
494
|
+
|
|
359
495
|
```bash
|
|
360
496
|
# Check current value
|
|
361
|
-
echo
|
|
497
|
+
echo $DIFFRON_MODEL # Linux/macOS
|
|
498
|
+
echo %DIFFRON_MODEL% # Windows
|
|
362
499
|
|
|
363
500
|
# Reset to recommended
|
|
364
501
|
diffron-setup-model --model qwen3.5-0.8b-gguf
|
|
@@ -369,6 +506,21 @@ diffron-setup-model
|
|
|
369
506
|
|
|
370
507
|
See [docs/SETUP.md](docs/SETUP.md) for complete troubleshooting guide.
|
|
371
508
|
|
|
509
|
+
### Diffron Not Generating Messages (AI Agent Detected)
|
|
510
|
+
|
|
511
|
+
**Symptom:** `git commit` works but Diffron doesn't generate a message.
|
|
512
|
+
|
|
513
|
+
**Cause:** An AI agent environment variable is detected (e.g., `CLAUDE_CODE_SESSION`, `CURSOR_SESSION_ID`).
|
|
514
|
+
|
|
515
|
+
**Solution:**
|
|
516
|
+
```bash
|
|
517
|
+
# Check what's being detected
|
|
518
|
+
diffron status
|
|
519
|
+
|
|
520
|
+
# If false positive, add the env var to exclude list
|
|
521
|
+
# (or unset the triggering env var)
|
|
522
|
+
```
|
|
523
|
+
|
|
372
524
|
---
|
|
373
525
|
|
|
374
526
|
## License
|
|
@@ -411,4 +563,4 @@ pytest tests/
|
|
|
411
563
|
|
|
412
564
|
---
|
|
413
565
|
|
|
414
|
-
*Version: 0.1.
|
|
566
|
+
*Version: 0.1.9 | Last updated: 2026-07-11*
|
|
@@ -10,6 +10,13 @@ from .lemonade import LemonadeClient, detect_lemonade_port
|
|
|
10
10
|
from .commit_gen import generate_commit_message
|
|
11
11
|
from .pr_gen import generate_pr_description, PRDescription
|
|
12
12
|
from .git_hooks import install_hooks, uninstall_hooks, is_hooks_installed
|
|
13
|
+
from .agent_detect import (
|
|
14
|
+
is_ai_agent_commit,
|
|
15
|
+
is_well_formed_commit,
|
|
16
|
+
list_known_agents,
|
|
17
|
+
list_agent_names,
|
|
18
|
+
get_agents_by_type,
|
|
19
|
+
)
|
|
13
20
|
from .models import (
|
|
14
21
|
ModelConfig,
|
|
15
22
|
list_available_models,
|
|
@@ -17,7 +24,7 @@ from .models import (
|
|
|
17
24
|
get_model_config,
|
|
18
25
|
)
|
|
19
26
|
|
|
20
|
-
__version__ = "0.1.
|
|
27
|
+
__version__ = "0.1.9"
|
|
21
28
|
__author__ = "Diffron Contributors"
|
|
22
29
|
__all__ = [
|
|
23
30
|
"DiffronClient",
|
|
@@ -29,6 +36,11 @@ __all__ = [
|
|
|
29
36
|
"install_hooks",
|
|
30
37
|
"uninstall_hooks",
|
|
31
38
|
"is_hooks_installed",
|
|
39
|
+
"is_ai_agent_commit",
|
|
40
|
+
"is_well_formed_commit",
|
|
41
|
+
"list_known_agents",
|
|
42
|
+
"list_agent_names",
|
|
43
|
+
"get_agents_by_type",
|
|
32
44
|
"ModelConfig",
|
|
33
45
|
"list_available_models",
|
|
34
46
|
"get_default_model",
|