diffron 0.1.0__py3-none-any.whl

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/utils.py ADDED
@@ -0,0 +1,236 @@
1
+ """
2
+ Shared utilities for Diffron.
3
+
4
+ Provides common functions for port scanning, Git operations, and file handling.
5
+ """
6
+
7
+ import subprocess
8
+ import socket
9
+ from typing import List, Optional
10
+ import psutil
11
+
12
+
13
+ COMMON_PORTS = [8000, 8001, 8080, 8081, 5000, 5001]
14
+
15
+
16
+ def scan_ports(ports: Optional[List[int]] = None, host: str = "localhost") -> List[int]:
17
+ """
18
+ Scan for open ports on the given host.
19
+
20
+ Args:
21
+ ports: List of ports to scan. Defaults to COMMON_PORTS.
22
+ host: Host to scan. Defaults to localhost.
23
+
24
+ Returns:
25
+ List of open ports.
26
+ """
27
+ if ports is None:
28
+ ports = COMMON_PORTS
29
+
30
+ open_ports = []
31
+ for port in ports:
32
+ if is_port_open(host, port):
33
+ open_ports.append(port)
34
+
35
+ return open_ports
36
+
37
+
38
+ def is_port_open(host: str, port: int, timeout: float = 1.0) -> bool:
39
+ """
40
+ Check if a port is open on the given host.
41
+
42
+ Args:
43
+ host: Host to check.
44
+ port: Port number to check.
45
+ timeout: Connection timeout in seconds.
46
+
47
+ Returns:
48
+ True if port is open, False otherwise.
49
+ """
50
+ try:
51
+ with socket.create_connection((host, port), timeout=timeout):
52
+ return True
53
+ except (socket.timeout, ConnectionRefusedError, OSError):
54
+ return False
55
+
56
+
57
+ def get_staged_diff(max_chars: int = 4000) -> str:
58
+ """
59
+ Get the staged git diff.
60
+
61
+ Args:
62
+ max_chars: Maximum number of characters to return.
63
+
64
+ Returns:
65
+ Staged diff as string, truncated to max_chars.
66
+ """
67
+ try:
68
+ result = subprocess.run(
69
+ ["git", "diff", "--cached"],
70
+ capture_output=True,
71
+ text=True,
72
+ errors="ignore",
73
+ timeout=30,
74
+ )
75
+ diff = result.stdout[:max_chars]
76
+ return diff
77
+ except (subprocess.SubprocessError, FileNotFoundError):
78
+ return ""
79
+
80
+
81
+ def get_branch_diff(branch: str, base: str = "main", max_chars: int = 5000) -> str:
82
+ """
83
+ Get the diff between a branch and its base.
84
+
85
+ Args:
86
+ branch: Branch name to compare.
87
+ base: Base branch to compare against.
88
+ max_chars: Maximum number of characters to return.
89
+
90
+ Returns:
91
+ Diff as string, truncated to max_chars.
92
+ """
93
+ try:
94
+ result = subprocess.run(
95
+ ["git", "diff", f"{base}..{branch}"],
96
+ capture_output=True,
97
+ text=True,
98
+ errors="ignore",
99
+ timeout=30,
100
+ )
101
+ diff = result.stdout[:max_chars]
102
+ return diff
103
+ except (subprocess.SubprocessError, FileNotFoundError):
104
+ return ""
105
+
106
+
107
+ def get_commit_log(branch: str, base: str = "main") -> str:
108
+ """
109
+ Get the commit log between a branch and its base.
110
+
111
+ Args:
112
+ branch: Branch name.
113
+ base: Base branch.
114
+
115
+ Returns:
116
+ Commit log as string (oneline format).
117
+ """
118
+ try:
119
+ result = subprocess.run(
120
+ ["git", "log", "--oneline", f"{base}..{branch}"],
121
+ capture_output=True,
122
+ text=True,
123
+ errors="ignore",
124
+ timeout=30,
125
+ )
126
+ return result.stdout
127
+ except (subprocess.SubprocessError, FileNotFoundError):
128
+ return ""
129
+
130
+
131
+ def get_current_branch() -> Optional[str]:
132
+ """
133
+ Get the current git branch name.
134
+
135
+ Returns:
136
+ Branch name or None if not in a git repo.
137
+ """
138
+ try:
139
+ result = subprocess.run(
140
+ ["git", "symbolic-ref", "--short", "HEAD"],
141
+ capture_output=True,
142
+ text=True,
143
+ errors="ignore",
144
+ timeout=10,
145
+ )
146
+ if result.returncode == 0:
147
+ return result.stdout.strip()
148
+ except (subprocess.SubprocessError, FileNotFoundError):
149
+ pass
150
+ return None
151
+
152
+
153
+ def is_git_repo(path: str = ".") -> bool:
154
+ """
155
+ Check if the given path is inside a git repository.
156
+
157
+ Args:
158
+ path: Path to check.
159
+
160
+ Returns:
161
+ True if inside a git repo, False otherwise.
162
+ """
163
+ try:
164
+ result = subprocess.run(
165
+ ["git", "rev-parse", "--git-dir"],
166
+ capture_output=True,
167
+ text=True,
168
+ cwd=path,
169
+ timeout=10,
170
+ )
171
+ return result.returncode == 0
172
+ except (subprocess.SubprocessError, FileNotFoundError):
173
+ return False
174
+
175
+
176
+ def get_git_dir(path: str = ".") -> Optional[str]:
177
+ """
178
+ Get the .git directory path.
179
+
180
+ Args:
181
+ path: Path to check.
182
+
183
+ Returns:
184
+ Absolute path to .git directory or None.
185
+ """
186
+ try:
187
+ result = subprocess.run(
188
+ ["git", "rev-parse", "--git-dir"],
189
+ capture_output=True,
190
+ text=True,
191
+ cwd=path,
192
+ timeout=10,
193
+ )
194
+ if result.returncode == 0:
195
+ git_dir = result.stdout.strip()
196
+ # Convert to absolute path
197
+ import os
198
+ if not os.path.isabs(git_dir):
199
+ git_dir = os.path.abspath(os.path.join(path, git_dir))
200
+ return git_dir
201
+ except (subprocess.SubprocessError, FileNotFoundError):
202
+ pass
203
+ return None
204
+
205
+
206
+ def find_default_branch() -> str:
207
+ """
208
+ Find the default branch (main or master).
209
+
210
+ Returns:
211
+ Default branch name.
212
+ """
213
+ try:
214
+ # Try main first (modern default)
215
+ result = subprocess.run(
216
+ ["git", "rev-parse", "--verify", "main"],
217
+ capture_output=True,
218
+ text=True,
219
+ timeout=10,
220
+ )
221
+ if result.returncode == 0:
222
+ return "main"
223
+
224
+ # Fall back to master
225
+ result = subprocess.run(
226
+ ["git", "rev-parse", "--verify", "master"],
227
+ capture_output=True,
228
+ text=True,
229
+ timeout=10,
230
+ )
231
+ if result.returncode == 0:
232
+ return "master"
233
+ except (subprocess.SubprocessError, FileNotFoundError):
234
+ pass
235
+
236
+ return "main" # Default to main
diffron/utils.pyi ADDED
@@ -0,0 +1,58 @@
1
+ """
2
+ Shared utilities for Diffron.
3
+
4
+ Provides common functions for port scanning, Git operations, and file handling.
5
+ """
6
+
7
+ from typing import List, Optional
8
+
9
+
10
+ COMMON_PORTS: List[int]
11
+
12
+
13
+ def scan_ports(
14
+ ports: Optional[List[int]] = None,
15
+ host: str = "localhost"
16
+ ) -> List[int]:
17
+ """Scan for open ports on the given host."""
18
+ ...
19
+
20
+
21
+ def is_port_open(host: str, port: int, timeout: float = 1.0) -> bool:
22
+ """Check if a port is open on the given host."""
23
+ ...
24
+
25
+
26
+ def get_staged_diff(max_chars: int = 4000) -> str:
27
+ """Get the staged git diff."""
28
+ ...
29
+
30
+
31
+ def get_branch_diff(branch: str, base: str = "main", max_chars: int = 5000) -> str:
32
+ """Get the diff between a branch and its base."""
33
+ ...
34
+
35
+
36
+ def get_commit_log(branch: str, base: str = "main") -> str:
37
+ """Get the commit log between a branch and its base."""
38
+ ...
39
+
40
+
41
+ def get_current_branch() -> Optional[str]:
42
+ """Get the current git branch name."""
43
+ ...
44
+
45
+
46
+ def is_git_repo(path: str = ".") -> bool:
47
+ """Check if the given path is inside a git repository."""
48
+ ...
49
+
50
+
51
+ def get_git_dir(path: str = ".") -> Optional[str]:
52
+ """Get the .git directory path."""
53
+ ...
54
+
55
+
56
+ def find_default_branch() -> str:
57
+ """Find the default branch (main or master)."""
58
+ ...
@@ -0,0 +1,373 @@
1
+ Metadata-Version: 2.4
2
+ Name: diffron
3
+ Version: 0.1.0
4
+ Summary: Git commit message and PR description generator using Lemonade
5
+ Home-page: https://github.com/diffron/diffron
6
+ Author: Diffron Contributors
7
+ Author-email: Diffron Contributors <diffron@example.com>
8
+ License: MIT
9
+ Project-URL: Homepage, https://github.com/diffron/diffron
10
+ Project-URL: Documentation, https://github.com/diffron/diffron/docs
11
+ Project-URL: Repository, https://github.com/diffron/diffron
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Environment :: Console
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Operating System :: Microsoft :: Windows
17
+ Classifier: Operating System :: POSIX :: Linux
18
+ Classifier: Operating System :: MacOS :: MacOS X
19
+ Classifier: Programming Language :: Python :: 3
20
+ Classifier: Programming Language :: Python :: 3.9
21
+ Classifier: Programming Language :: Python :: 3.10
22
+ Classifier: Programming Language :: Python :: 3.11
23
+ Classifier: Programming Language :: Python :: 3.12
24
+ Classifier: Topic :: Software Development :: Version Control :: Git
25
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
26
+ Requires-Python: >=3.9
27
+ Description-Content-Type: text/markdown
28
+ License-File: LICENSE
29
+ Requires-Dist: openai>=1.0.0
30
+ Requires-Dist: psutil>=5.9.0
31
+ Provides-Extra: git
32
+ Requires-Dist: gitpython>=3.1.0; extra == "git"
33
+ Provides-Extra: dev
34
+ Requires-Dist: pytest>=7.0.0; extra == "dev"
35
+ Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
36
+ Requires-Dist: black>=23.0.0; extra == "dev"
37
+ Requires-Dist: isort>=5.12.0; extra == "dev"
38
+ Requires-Dist: mypy>=1.0.0; extra == "dev"
39
+ Dynamic: author
40
+ Dynamic: home-page
41
+ Dynamic: license-file
42
+ Dynamic: requires-python
43
+
44
+ # Diffron
45
+
46
+ Git commit message and PR description generator using AMD Lemonade via lemonade-python-sdk.
47
+
48
+ **This is a demo project showcasing the lemonade-python-sdk - submitted to the AMD Lemonade Developer Challenge 2026.**
49
+
50
+ ![Version](https://img.shields.io/badge/version-0.1.0-blue)
51
+ ![Python](https://img.shields.io/badge/python-3.9+-blue)
52
+ ![License](https://img.shields.io/badge/license-MIT-green)
53
+ ![Platform](https://img.shields.io/badge/platform-Windows-lightgrey)
54
+
55
+ ---
56
+
57
+ ## Features
58
+
59
+ - 🤖 **Auto Commit Messages** - Generates Conventional Commits format messages from your staged changes
60
+ - 📝 **PR Descriptions** - Creates detailed PR titles and descriptions from branch diffs
61
+ - 🔌 **Lemonade Integration** - Works with your local Lemonade LLM server (no cloud required)
62
+ - 🪟 **Windows Ready** - Fully compatible with GitHub Desktop 3.5.5+ hooks support
63
+ - ⚡ **Auto-Detection** - Automatically finds your running Lemonade instance
64
+ - 🎯 **Model Flexible** - Use any Lemonade-compatible model (default: qwen2.5-it-3b-FLM)
65
+
66
+ ---
67
+
68
+ ## Quick Start
69
+
70
+ ### 1. Install AMD Lemonade Server
71
+
72
+ **Lemonade is AMD's local LLM server for Ryzen AI PCs.**
73
+
74
+ 1. Download the installer from [AMD Lemonade Releases](https://github.com/AMD-AI-Software/lemonade/releases)
75
+ 2. Run `Lemonade_Server_Installer.exe`
76
+ 3. Launch Lemonade Server from the desktop shortcut
77
+ 4. Download a model via the Lemonade UI (e.g., `qwen2.5-it-3b-FLM`)
78
+
79
+ 📚 **Documentation:** [AMD Ryzen AI - Lemonade Setup](https://ryzenai.docs.amd.com/en/latest/llm/server_interface.html)
80
+
81
+ ### 2. Install lemonade-python-sdk
82
+
83
+ **Our Python SDK for AMD Lemonade API:**
84
+
85
+ ```bash
86
+ pip install lemonade-sdk
87
+ ```
88
+
89
+ 🔗 **Source:** [github.com/Tetramatrix/lemonade-python-sdk](https://github.com/Tetramatrix/lemonade-python-sdk)
90
+
91
+ ### 3. Configure Environment
92
+
93
+ **Set Lemonade Server URL (Permanent):**
94
+ 1. System Properties → Environment Variables
95
+ 2. New User Variable:
96
+ - Name: `LEMONADE_SERVER_URL`
97
+ - Value: `http://localhost:8020`
98
+
99
+ **Or Temporary (current session):**
100
+ ```cmd
101
+ set LEMONADE_SERVER_URL=http://localhost:8020
102
+ ```
103
+
104
+ ### 4. Install Diffron
105
+
106
+ ```bash
107
+ pip install diffron
108
+ ```
109
+
110
+ ### 5. Install Git Hooks
111
+
112
+ ```bash
113
+ python -c "from diffron.git_hooks import install_hooks; install_hooks(global_install=True)"
114
+ ```
115
+
116
+ ### 6. Test It
117
+
118
+ ```bash
119
+ # Make a change
120
+ echo "test" > test.txt
121
+ git add test.txt
122
+
123
+ # Commit - hooks generate the message automatically!
124
+ git commit -m "anything"
125
+ ```
126
+
127
+ Expected output:
128
+ ```
129
+ [master abc123] feat: add test.txt file
130
+ 1 file changed, 1 insertion(+)
131
+ ```
132
+
133
+ ---
134
+
135
+ ## Installation
136
+
137
+ ### Requirements
138
+
139
+ | Software | Version | Purpose |
140
+ |----------|---------|---------|
141
+ | Python | 3.9+ | Runtime |
142
+ | Git | 2.0+ | Version control |
143
+ | GitHub Desktop | 3.5.5+ | Git GUI (Windows) |
144
+ | lemonade-sdk | Latest | AMD Lemonade API client |
145
+ | Lemonade | Latest | Local LLM server |
146
+
147
+ ### Full Installation Guide
148
+
149
+ See [docs/SETUP.md](docs/SETUP.md) for detailed Windows-specific instructions.
150
+
151
+ ---
152
+
153
+ ## Usage
154
+
155
+ ### CLI Commands
156
+
157
+ ```bash
158
+ # Install hooks globally
159
+ python -c "from diffron.git_hooks import install_hooks; install_hooks(global_install=True)"
160
+
161
+ # Generate PR description
162
+ python -c "from diffron import generate_pr_description; pr = generate_pr_description(); print(pr.format_output())"
163
+
164
+ # Check status
165
+ python -c "from diffron import is_lemonade_running, is_hooks_installed; print('Lemonade:', is_lemonade_running()); print('Hooks:', is_hooks_installed(check_global=True))"
166
+ ```
167
+
168
+ ### Python API
169
+
170
+ ```python
171
+ from diffron import DiffronClient
172
+
173
+ # Create client
174
+ client = DiffronClient()
175
+
176
+ # Generate commit message
177
+ msg = client.generate_commit_message()
178
+ print(msg) # "feat: add user authentication"
179
+
180
+ # Generate PR description
181
+ pr = client.generate_pr_description(branch="feature/my-feature")
182
+ print(f"TITLE: {pr.title}")
183
+ print(f"DESCRIPTION: {pr.description}")
184
+
185
+ # Install hooks
186
+ client.install_hooks(global_install=True)
187
+ ```
188
+
189
+ ### GitHub Desktop Workflow
190
+
191
+ 1. Make changes to your files
192
+ 2. Open GitHub Desktop
193
+ 3. Enter any commit message (e.g., "auto")
194
+ 4. Click "Commit to main"
195
+ 5. **Diffron replaces** your message with AI-generated message
196
+
197
+ ---
198
+
199
+ ## Configuration
200
+
201
+ ### Environment Variables
202
+
203
+ | Variable | Default | Description |
204
+ |----------|---------|-------------|
205
+ | `LEMONADE_SERVER_URL` | `http://localhost:8020` | Lemonade server URL |
206
+ | `DIFFRON_MODEL` | `qwen2.5-it-3b-FLM` | Model name to use |
207
+ | `DIFFRON_MAX_DIFF_CHARS` | `4000` | Max diff characters |
208
+
209
+ ### Change Model
210
+
211
+ ```cmd
212
+ # System-wide
213
+ setx DIFFRON_MODEL "qwen2.5-coder-7b"
214
+
215
+ # Current session
216
+ set DIFFRON_MODEL=qwen2.5-coder-7b
217
+ ```
218
+
219
+ ### Python API
220
+
221
+ ```python
222
+ from diffron import DiffronClient
223
+
224
+ # Use different model
225
+ client = DiffronClient(model="your-model-name")
226
+ ```
227
+
228
+ ---
229
+
230
+ ## Documentation
231
+
232
+ | Document | Description |
233
+ |----------|-------------|
234
+ | [SETUP.md](docs/SETUP.md) | Complete installation guide for Windows |
235
+ | [HOOKS.md](docs/HOOKS.md) | Git hooks architecture and internals |
236
+ | [USAGE.md](docs/USAGE.md) | Detailed usage examples |
237
+
238
+ ---
239
+
240
+ ## Related Projects
241
+
242
+ ### Tetramatrix Projects
243
+
244
+ | Project | Description |
245
+ |---------|-------------|
246
+ | **lemonade-python-sdk** | 🍋 **AMD Lemonade Challenge Submission** - Python SDK for AMD Lemonade API |
247
+ | **Diffron** | Demo project showcasing lemonade-python-sdk (this repo) |
248
+ | **Aicono** | AI Assistant (Desktop App) |
249
+ | **TabNeuron** | Browser Connector / Memory |
250
+ | **Sorana** | Advanced AI Interface |
251
+ | **RyzenPilot** | Hardware Optimization |
252
+
253
+ **Note:** Lemonade is AMD's local LLM server for Ryzen AI PCs. Diffron uses `lemonade-python-sdk` to communicate with Lemonade's API.
254
+
255
+ 🏆 **AMD Lemonade Developer Challenge 2026:** This project demonstrates the capabilities of lemonade-python-sdk as a real-world application built on AMD Lemonade.
256
+
257
+ ---
258
+
259
+ ## How It Works
260
+
261
+ ```
262
+ ┌─────────────────────────────────────────────────────────┐
263
+ │ 1. User makes changes and runs: git commit │
264
+ └─────────────────────────────────────────────────────────┘
265
+
266
+ ┌─────────────────────────────────────────────────────────┐
267
+ │ 2. Git hook executes prepare-commit-msg │
268
+ │ - Location: C:/Users/Name/.diffron-hooks/ │
269
+ └─────────────────────────────────────────────────────────┘
270
+
271
+ ┌─────────────────────────────────────────────────────────┐
272
+ │ 3. Hook reads staged diff: git diff --cached │
273
+ └─────────────────────────────────────────────────────────┘
274
+
275
+ ┌─────────────────────────────────────────────────────────┐
276
+ │ 4. Hook calls Lemonade API │
277
+ │ - URL: http://localhost:8020/api/v1 │
278
+ │ - Model: qwen2.5-it-3b-FLM │
279
+ └─────────────────────────────────────────────────────────┘
280
+
281
+ ┌─────────────────────────────────────────────────────────┐
282
+ │ 5. AI generates Conventional Commit message │
283
+ │ - "feat: add user authentication module" │
284
+ └─────────────────────────────────────────────────────────┘
285
+
286
+ ┌─────────────────────────────────────────────────────────┐
287
+ │ 6. Git opens editor with generated message │
288
+ │ - User can review/modify before saving │
289
+ └─────────────────────────────────────────────────────────┘
290
+ ```
291
+
292
+ ---
293
+
294
+ ## Troubleshooting
295
+
296
+ ### Lemonade Not Detected
297
+
298
+ ```bash
299
+ # Start Lemonade
300
+ lemonade serve qwen2.5-it-3b-FLM
301
+
302
+ # Verify URL
303
+ echo %LEMONADE_SERVER_URL%
304
+ ```
305
+
306
+ ### Hooks Not Working
307
+
308
+ ```bash
309
+ # Check GitHub Desktop version (must be 3.5.5+)
310
+ # Help → About
311
+
312
+ # Verify hooks path
313
+ git config --global core.hooksPath
314
+
315
+ # Reinstall hooks
316
+ python -c "from diffron.git_hooks import install_hooks; install_hooks(global_install=True)"
317
+ ```
318
+
319
+ ### Model Not Found (404)
320
+
321
+ ```bash
322
+ # Download model
323
+ lemonade pull qwen2.5-it-3b-FLM
324
+
325
+ # Verify model name
326
+ set DIFFRON_MODEL=qwen2.5-it-3b-FLM
327
+ ```
328
+
329
+ See [docs/SETUP.md](docs/SETUP.md) for complete troubleshooting guide.
330
+
331
+ ---
332
+
333
+ ## License
334
+
335
+ MIT License - see [LICENSE](LICENSE) for details.
336
+
337
+ ---
338
+
339
+ ## Contributing
340
+
341
+ Contributions welcome! This is an open source project.
342
+
343
+ 1. Fork the repository
344
+ 2. Create a feature branch
345
+ 3. Make your changes
346
+ 4. Run tests
347
+ 5. Submit a pull request
348
+
349
+ ### Development Setup
350
+
351
+ ```bash
352
+ git clone https://github.com/diffron/diffron.git
353
+ cd diffron
354
+ pip install -e ".[dev]"
355
+ ```
356
+
357
+ ### Run Tests
358
+
359
+ ```bash
360
+ pytest tests/
361
+ ```
362
+
363
+ ---
364
+
365
+ ## Acknowledgments
366
+
367
+ - **Lemonade** - Local LLM server by the Lemonade team
368
+ - **GitHub Desktop** - Git GUI with hooks support (3.5.5+)
369
+ - **Conventional Commits** - Commit message format specification
370
+
371
+ ---
372
+
373
+ *Version: 0.1.0 | Last updated: 2026-03-28*
@@ -0,0 +1,28 @@
1
+ diffron/__init__.py,sha256=zWh5clvGKqkTWP4i5BuG4uzzBAV0WOz5cb66noH3n6w,730
2
+ diffron/__init__.pyi,sha256=narREZbkyqZeyb6uFKMqSJDjdisbP7bwdH6I_qpk8Ik,712
3
+ diffron/cli.py,sha256=-bVwq_gdepyBgGiNutSO7VZOkzR56bBdF_eCa5ldo6Y,9673
4
+ diffron/cli.pyi,sha256=DRx5Uvg9YoOfLIzhCRArLHXpddaADZoose94oOSxHu8,550
5
+ diffron/client.py,sha256=6C69FGEiqMPhL_qVfpXjV-V4tsIyTssxwXKdzF-FPzA,5122
6
+ diffron/client.pyi,sha256=eEcSY2kJHiuYcKGJ7KnaIcvY92xlm4b-yXV9ITf4GBg,2087
7
+ diffron/commit_gen.py,sha256=IJTadg5ttvWFl0X1aLREprHvBr4AAHlhKLMxN2fMjT4,4560
8
+ diffron/commit_gen.pyi,sha256=-3MZezLNCfXIHzsIQdiWYVZ_1gMBzH51vH9pnICpKmc,949
9
+ diffron/git_hooks.py,sha256=ScyEfwZVID4yuniRVEEBOoVWqQ2tzvoR2kJPLTjoqFQ,8218
10
+ diffron/git_hooks.pyi,sha256=HPMhxzGG3-Jqsnn95fwWU535-IiQAR1faRD9HcpJvAI,1027
11
+ diffron/lemonade.py,sha256=y1YUWLWlrEiyTnn_YJVrc8qU3-2990hORGj-IMNoTlA,5600
12
+ diffron/lemonade.pyi,sha256=Z3dvqsstOwA5eHTu2oBXmaECyCBZLz-RmzsHDwRXlUM,1350
13
+ diffron/pr_gen.py,sha256=84qZUf1IXsxv27HxCfqi5yFvJ6lOeCaK87KlDVVNwVA,6560
14
+ diffron/pr_gen.pyi,sha256=oMm9Q9cNwzT9kpAhaWqiGMZxnpdCteyPQdV-eai0c98,1317
15
+ diffron/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
+ diffron/utils.py,sha256=-YbCIm8rAGiDBYZahMZgUJ17r3NlpEX-FX97nsz5mp0,5831
17
+ diffron/utils.pyi,sha256=LnxeTcOSucvfg4jszVBI8cYHoqUnkgaOiK4PmUJKPU8,1251
18
+ diffron-0.1.0.dist-info/licenses/LICENSE,sha256=Lyind8rORjrnAcM4YCvqvlklEUaeZSTzqmA2QiRrAGY,1077
19
+ docs/HOOKS.md,sha256=2l138u33rcQeBFEIhpOcECneg2HHMs7EdQ1JCDtWxKQ,13778
20
+ docs/PLAN.md,sha256=_fBS3zWcaxcW4Npss66-YLDn_lrAZyhSnjreTLK8cfU,11217
21
+ docs/PYPI_RELEASE.md,sha256=sl_vT6x_piPNDfymfCHNpM_j0OwY3ZGbxRAMUy8RCa4,8729
22
+ docs/SETUP.md,sha256=Uy_1_AGN0i4JPigPquZWb2YXijd5Yzz-Fn5zwcgTfEs,13023
23
+ docs/USAGE.md,sha256=hYDQQZdKcUIUUrdDG51LVzHduMQgxwNNdYGBvOgMea8,9878
24
+ diffron-0.1.0.dist-info/METADATA,sha256=tAYHQcHWd1zDPdpRpkmOkFRPXgsXcK_1Z_1IXrxkF9Q,12136
25
+ diffron-0.1.0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
26
+ diffron-0.1.0.dist-info/entry_points.txt,sha256=IRWRl2dBVxsXKNcV45trz4E22WjDDAI1xr5U8_CILmA,214
27
+ diffron-0.1.0.dist-info/top_level.txt,sha256=xRWBliiMzDBMb-K_izgUOMcVqj88-EXLhZbJU4Nl-EA,13
28
+ diffron-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (82.0.1)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,5 @@
1
+ [console_scripts]
2
+ diffron-install-hooks = diffron.cli:install_hooks_cli
3
+ diffron-pr = diffron.cli:pr_description_cli
4
+ diffron-status = diffron.cli:status_cli
5
+ diffron-uninstall-hooks = diffron.cli:uninstall_hooks_cli