laminate-cli 0.1.3__tar.gz → 0.1.5__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.
- {laminate_cli-0.1.3 → laminate_cli-0.1.5}/PKG-INFO +24 -18
- {laminate_cli-0.1.3 → laminate_cli-0.1.5}/README.md +23 -18
- {laminate_cli-0.1.3 → laminate_cli-0.1.5}/laminate/cli.py +19 -0
- {laminate_cli-0.1.3 → laminate_cli-0.1.5}/laminate/llm.py +33 -25
- {laminate_cli-0.1.3 → laminate_cli-0.1.5}/laminate_cli.egg-info/PKG-INFO +24 -18
- {laminate_cli-0.1.3 → laminate_cli-0.1.5}/laminate_cli.egg-info/requires.txt +1 -0
- {laminate_cli-0.1.3 → laminate_cli-0.1.5}/pyproject.toml +3 -2
- {laminate_cli-0.1.3 → laminate_cli-0.1.5}/LICENSE +0 -0
- {laminate_cli-0.1.3 → laminate_cli-0.1.5}/laminate/__init__.py +0 -0
- {laminate_cli-0.1.3 → laminate_cli-0.1.5}/laminate/categorize.py +0 -0
- {laminate_cli-0.1.3 → laminate_cli-0.1.5}/laminate/gitlog.py +0 -0
- {laminate_cli-0.1.3 → laminate_cli-0.1.5}/laminate/render.py +0 -0
- {laminate_cli-0.1.3 → laminate_cli-0.1.5}/laminate_cli.egg-info/SOURCES.txt +0 -0
- {laminate_cli-0.1.3 → laminate_cli-0.1.5}/laminate_cli.egg-info/dependency_links.txt +0 -0
- {laminate_cli-0.1.3 → laminate_cli-0.1.5}/laminate_cli.egg-info/entry_points.txt +0 -0
- {laminate_cli-0.1.3 → laminate_cli-0.1.5}/laminate_cli.egg-info/top_level.txt +0 -0
- {laminate_cli-0.1.3 → laminate_cli-0.1.5}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: laminate-cli
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.5
|
|
4
4
|
Summary: Generate release-ready changelogs from git history using a local LLM
|
|
5
5
|
Author-email: Apleut <me@apleut.dev>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -20,6 +20,7 @@ Requires-Dist: llama-cpp-python
|
|
|
20
20
|
Requires-Dist: pydantic
|
|
21
21
|
Requires-Dist: typer
|
|
22
22
|
Requires-Dist: rich
|
|
23
|
+
Requires-Dist: platformdirs
|
|
23
24
|
Dynamic: license-file
|
|
24
25
|
|
|
25
26
|
<div style="text-align: center;">
|
|
@@ -104,18 +105,28 @@ pip install laminate-cli
|
|
|
104
105
|
|
|
105
106
|
Laminate runs a **local GGUF model** using [`llama-cpp-python`](https://github.com/abetlen/llama-cpp-python).
|
|
106
107
|
|
|
107
|
-
|
|
108
|
+
[Phi-4-mini-instruct](https://huggingface.co/unsloth/Phi-4-mini-instruct-GGUF) is a good pick, and is the model used for Laminate's development.
|
|
108
109
|
|
|
109
|
-
|
|
110
|
-
models/
|
|
111
|
-
└── your-model.gguf
|
|
112
|
-
```
|
|
110
|
+
Laminate looks for exactly one `.gguf` file in two places, in this order:
|
|
113
111
|
|
|
114
|
-
|
|
112
|
+
1. **A `models/` folder in your current directory**, which is the recommended location if you're running Laminate from a cloned repo:
|
|
113
|
+
|
|
114
|
+
```text
|
|
115
|
+
models/
|
|
116
|
+
└── your-model.gguf
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
2. **Your OS's standard application data folder**, under `Laminate/models/`, used automatically if no local `models/` folder is found. This is the normal location if you installed via `pip install laminate-cli`:
|
|
120
|
+
|
|
121
|
+
| OS | Location |
|
|
122
|
+
|---|---|
|
|
123
|
+
| Windows | `%LOCALAPPDATA%\Apleut\Laminate\models\` |
|
|
124
|
+
| macOS | `~/Library/Application Support/Laminate/models/` |
|
|
125
|
+
| Linux | `~/.local/share/Laminate/models/` |
|
|
115
126
|
|
|
116
|
-
|
|
127
|
+
Create the folder if it doesn't already exist, and place your `.gguf` file inside.
|
|
117
128
|
|
|
118
|
-
If
|
|
129
|
+
If Laminate can't find a model, or finds more than one `.gguf` file in whichever folder it checks, it will stop and tell you exactly which locations it looked in and what to fix.
|
|
119
130
|
|
|
120
131
|
The model is intentionally kept separate from the package because GGUF models can be large and have different licensing requirements.
|
|
121
132
|
|
|
@@ -127,11 +138,7 @@ From inside a Git repository:
|
|
|
127
138
|
laminate
|
|
128
139
|
```
|
|
129
140
|
|
|
130
|
-
Laminate will read the repository's commit history, categorize the changes, and write the result to
|
|
131
|
-
|
|
132
|
-
```text
|
|
133
|
-
CHANGELOG.md
|
|
134
|
-
```
|
|
141
|
+
Laminate will read the repository's commit history, categorize the changes, and write the result to `CHANGELOG.md`
|
|
135
142
|
|
|
136
143
|
For example:
|
|
137
144
|
|
|
@@ -181,6 +188,9 @@ Process a specific Git commit range.
|
|
|
181
188
|
laminate --range v1.0.0..v1.1.0
|
|
182
189
|
```
|
|
183
190
|
|
|
191
|
+
> [!IMPORTANT]
|
|
192
|
+
> Laminate does not currently support range formats like `v1.0.0..HEAD`. Version-to-present functionality will be added in a future release.
|
|
193
|
+
|
|
184
194
|
`--range` overrides `--since` and `--until`.
|
|
185
195
|
|
|
186
196
|
This is particularly useful when generating a changelog for a release.
|
|
@@ -308,7 +318,3 @@ If you find a problem with Laminate, please open an issue with:
|
|
|
308
318
|
Or email me at [me@apleut.dev](me@apleut.dev).
|
|
309
319
|
|
|
310
320
|
For changes to Laminate itself, pull requests are welcome.
|
|
311
|
-
|
|
312
|
-
## License
|
|
313
|
-
|
|
314
|
-
License information will be added before the first stable release.
|
|
@@ -80,18 +80,28 @@ pip install laminate-cli
|
|
|
80
80
|
|
|
81
81
|
Laminate runs a **local GGUF model** using [`llama-cpp-python`](https://github.com/abetlen/llama-cpp-python).
|
|
82
82
|
|
|
83
|
-
|
|
83
|
+
[Phi-4-mini-instruct](https://huggingface.co/unsloth/Phi-4-mini-instruct-GGUF) is a good pick, and is the model used for Laminate's development.
|
|
84
84
|
|
|
85
|
-
|
|
86
|
-
models/
|
|
87
|
-
└── your-model.gguf
|
|
88
|
-
```
|
|
85
|
+
Laminate looks for exactly one `.gguf` file in two places, in this order:
|
|
89
86
|
|
|
90
|
-
|
|
87
|
+
1. **A `models/` folder in your current directory**, which is the recommended location if you're running Laminate from a cloned repo:
|
|
88
|
+
|
|
89
|
+
```text
|
|
90
|
+
models/
|
|
91
|
+
└── your-model.gguf
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
2. **Your OS's standard application data folder**, under `Laminate/models/`, used automatically if no local `models/` folder is found. This is the normal location if you installed via `pip install laminate-cli`:
|
|
95
|
+
|
|
96
|
+
| OS | Location |
|
|
97
|
+
|---|---|
|
|
98
|
+
| Windows | `%LOCALAPPDATA%\Apleut\Laminate\models\` |
|
|
99
|
+
| macOS | `~/Library/Application Support/Laminate/models/` |
|
|
100
|
+
| Linux | `~/.local/share/Laminate/models/` |
|
|
91
101
|
|
|
92
|
-
|
|
102
|
+
Create the folder if it doesn't already exist, and place your `.gguf` file inside.
|
|
93
103
|
|
|
94
|
-
If
|
|
104
|
+
If Laminate can't find a model, or finds more than one `.gguf` file in whichever folder it checks, it will stop and tell you exactly which locations it looked in and what to fix.
|
|
95
105
|
|
|
96
106
|
The model is intentionally kept separate from the package because GGUF models can be large and have different licensing requirements.
|
|
97
107
|
|
|
@@ -103,11 +113,7 @@ From inside a Git repository:
|
|
|
103
113
|
laminate
|
|
104
114
|
```
|
|
105
115
|
|
|
106
|
-
Laminate will read the repository's commit history, categorize the changes, and write the result to
|
|
107
|
-
|
|
108
|
-
```text
|
|
109
|
-
CHANGELOG.md
|
|
110
|
-
```
|
|
116
|
+
Laminate will read the repository's commit history, categorize the changes, and write the result to `CHANGELOG.md`
|
|
111
117
|
|
|
112
118
|
For example:
|
|
113
119
|
|
|
@@ -157,6 +163,9 @@ Process a specific Git commit range.
|
|
|
157
163
|
laminate --range v1.0.0..v1.1.0
|
|
158
164
|
```
|
|
159
165
|
|
|
166
|
+
> [!IMPORTANT]
|
|
167
|
+
> Laminate does not currently support range formats like `v1.0.0..HEAD`. Version-to-present functionality will be added in a future release.
|
|
168
|
+
|
|
160
169
|
`--range` overrides `--since` and `--until`.
|
|
161
170
|
|
|
162
171
|
This is particularly useful when generating a changelog for a release.
|
|
@@ -283,8 +292,4 @@ If you find a problem with Laminate, please open an issue with:
|
|
|
283
292
|
|
|
284
293
|
Or email me at [me@apleut.dev](me@apleut.dev).
|
|
285
294
|
|
|
286
|
-
For changes to Laminate itself, pull requests are welcome.
|
|
287
|
-
|
|
288
|
-
## License
|
|
289
|
-
|
|
290
|
-
License information will be added before the first stable release.
|
|
295
|
+
For changes to Laminate itself, pull requests are welcome.
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import typer
|
|
2
2
|
|
|
3
3
|
from concurrent.futures import ThreadPoolExecutor
|
|
4
|
+
from importlib.metadata import version as get_version, PackageNotFoundError
|
|
4
5
|
|
|
5
6
|
import sys
|
|
6
7
|
|
|
@@ -17,6 +18,17 @@ app = typer.Typer(add_completion=False)
|
|
|
17
18
|
console = Console()
|
|
18
19
|
|
|
19
20
|
|
|
21
|
+
def _version_callback(value: bool):
|
|
22
|
+
if not value:
|
|
23
|
+
return
|
|
24
|
+
try:
|
|
25
|
+
v = get_version("laminate-cli")
|
|
26
|
+
except PackageNotFoundError:
|
|
27
|
+
v = "unknown (not installed as a package)"
|
|
28
|
+
typer.echo(f"laminate {v}")
|
|
29
|
+
raise typer.Exit()
|
|
30
|
+
|
|
31
|
+
|
|
20
32
|
@app.command()
|
|
21
33
|
def generate(
|
|
22
34
|
repo: str = typer.Option(".", help="Path to the git repository."),
|
|
@@ -26,6 +38,13 @@ def generate(
|
|
|
26
38
|
output: str = typer.Option("CHANGELOG.md", help="Path to write the generated changelog to."),
|
|
27
39
|
batch_size: int = typer.Option(15, "--batch-size", help="Number of commits sent to the LLM per batch."),
|
|
28
40
|
release: str = typer.Option(None, "--release", help="Version number for this release, e.g. 1.1.0. If omitted, the changelog is headed [Unreleased]."),
|
|
41
|
+
version: bool = typer.Option(
|
|
42
|
+
False,
|
|
43
|
+
"--version",
|
|
44
|
+
callback=_version_callback,
|
|
45
|
+
is_eager=True,
|
|
46
|
+
help="Show Laminate's version and exit.",
|
|
47
|
+
),
|
|
29
48
|
):
|
|
30
49
|
if repo != ".":
|
|
31
50
|
typer.echo(f"Reading commits from '{repo}'...")
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
from pathlib import Path
|
|
2
2
|
from llama_cpp import Llama
|
|
3
|
+
from platformdirs import user_data_dir
|
|
3
4
|
|
|
4
|
-
|
|
5
|
+
_CANDIDATE_DIRS = [
|
|
6
|
+
Path.cwd() / "models",
|
|
7
|
+
Path(user_data_dir("Laminate", "Apleut")) / "models",
|
|
8
|
+
]
|
|
5
9
|
|
|
6
|
-
DEFAULT_N_CTX = 4096
|
|
10
|
+
DEFAULT_N_CTX = 4096
|
|
7
11
|
_llm: Llama | None = None
|
|
8
12
|
|
|
9
13
|
|
|
@@ -12,29 +16,33 @@ class LLMError(Exception):
|
|
|
12
16
|
|
|
13
17
|
|
|
14
18
|
def _find_model_file() -> Path:
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
)
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
)
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
19
|
+
checked = []
|
|
20
|
+
|
|
21
|
+
for candidate_dir in _CANDIDATE_DIRS:
|
|
22
|
+
checked.append(str(candidate_dir))
|
|
23
|
+
|
|
24
|
+
if not candidate_dir.exists():
|
|
25
|
+
continue
|
|
26
|
+
|
|
27
|
+
gguf_files = list(candidate_dir.glob("*.gguf"))
|
|
28
|
+
|
|
29
|
+
if len(gguf_files) == 1:
|
|
30
|
+
return gguf_files[0]
|
|
31
|
+
|
|
32
|
+
if len(gguf_files) > 1:
|
|
33
|
+
names = ", ".join(f.name for f in gguf_files)
|
|
34
|
+
raise LLMError(
|
|
35
|
+
f"Multiple .gguf files found in {candidate_dir} ({names}) - "
|
|
36
|
+
"keep only one so Laminate knows which to load."
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
checked_str = "\n - ".join(checked)
|
|
40
|
+
raise LLMError(
|
|
41
|
+
"No .gguf model file found. Laminate checked:\n - "
|
|
42
|
+
f"{checked_str}\n"
|
|
43
|
+
"Download a compatible model (see README) and place it in one "
|
|
44
|
+
"of those folders (create the folder if it doesn't exist)."
|
|
45
|
+
)
|
|
38
46
|
|
|
39
47
|
|
|
40
48
|
def get_llm(n_ctx: int = DEFAULT_N_CTX) -> Llama:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: laminate-cli
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.5
|
|
4
4
|
Summary: Generate release-ready changelogs from git history using a local LLM
|
|
5
5
|
Author-email: Apleut <me@apleut.dev>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -20,6 +20,7 @@ Requires-Dist: llama-cpp-python
|
|
|
20
20
|
Requires-Dist: pydantic
|
|
21
21
|
Requires-Dist: typer
|
|
22
22
|
Requires-Dist: rich
|
|
23
|
+
Requires-Dist: platformdirs
|
|
23
24
|
Dynamic: license-file
|
|
24
25
|
|
|
25
26
|
<div style="text-align: center;">
|
|
@@ -104,18 +105,28 @@ pip install laminate-cli
|
|
|
104
105
|
|
|
105
106
|
Laminate runs a **local GGUF model** using [`llama-cpp-python`](https://github.com/abetlen/llama-cpp-python).
|
|
106
107
|
|
|
107
|
-
|
|
108
|
+
[Phi-4-mini-instruct](https://huggingface.co/unsloth/Phi-4-mini-instruct-GGUF) is a good pick, and is the model used for Laminate's development.
|
|
108
109
|
|
|
109
|
-
|
|
110
|
-
models/
|
|
111
|
-
└── your-model.gguf
|
|
112
|
-
```
|
|
110
|
+
Laminate looks for exactly one `.gguf` file in two places, in this order:
|
|
113
111
|
|
|
114
|
-
|
|
112
|
+
1. **A `models/` folder in your current directory**, which is the recommended location if you're running Laminate from a cloned repo:
|
|
113
|
+
|
|
114
|
+
```text
|
|
115
|
+
models/
|
|
116
|
+
└── your-model.gguf
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
2. **Your OS's standard application data folder**, under `Laminate/models/`, used automatically if no local `models/` folder is found. This is the normal location if you installed via `pip install laminate-cli`:
|
|
120
|
+
|
|
121
|
+
| OS | Location |
|
|
122
|
+
|---|---|
|
|
123
|
+
| Windows | `%LOCALAPPDATA%\Apleut\Laminate\models\` |
|
|
124
|
+
| macOS | `~/Library/Application Support/Laminate/models/` |
|
|
125
|
+
| Linux | `~/.local/share/Laminate/models/` |
|
|
115
126
|
|
|
116
|
-
|
|
127
|
+
Create the folder if it doesn't already exist, and place your `.gguf` file inside.
|
|
117
128
|
|
|
118
|
-
If
|
|
129
|
+
If Laminate can't find a model, or finds more than one `.gguf` file in whichever folder it checks, it will stop and tell you exactly which locations it looked in and what to fix.
|
|
119
130
|
|
|
120
131
|
The model is intentionally kept separate from the package because GGUF models can be large and have different licensing requirements.
|
|
121
132
|
|
|
@@ -127,11 +138,7 @@ From inside a Git repository:
|
|
|
127
138
|
laminate
|
|
128
139
|
```
|
|
129
140
|
|
|
130
|
-
Laminate will read the repository's commit history, categorize the changes, and write the result to
|
|
131
|
-
|
|
132
|
-
```text
|
|
133
|
-
CHANGELOG.md
|
|
134
|
-
```
|
|
141
|
+
Laminate will read the repository's commit history, categorize the changes, and write the result to `CHANGELOG.md`
|
|
135
142
|
|
|
136
143
|
For example:
|
|
137
144
|
|
|
@@ -181,6 +188,9 @@ Process a specific Git commit range.
|
|
|
181
188
|
laminate --range v1.0.0..v1.1.0
|
|
182
189
|
```
|
|
183
190
|
|
|
191
|
+
> [!IMPORTANT]
|
|
192
|
+
> Laminate does not currently support range formats like `v1.0.0..HEAD`. Version-to-present functionality will be added in a future release.
|
|
193
|
+
|
|
184
194
|
`--range` overrides `--since` and `--until`.
|
|
185
195
|
|
|
186
196
|
This is particularly useful when generating a changelog for a release.
|
|
@@ -308,7 +318,3 @@ If you find a problem with Laminate, please open an issue with:
|
|
|
308
318
|
Or email me at [me@apleut.dev](me@apleut.dev).
|
|
309
319
|
|
|
310
320
|
For changes to Laminate itself, pull requests are welcome.
|
|
311
|
-
|
|
312
|
-
## License
|
|
313
|
-
|
|
314
|
-
License information will be added before the first stable release.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "laminate-cli"
|
|
3
|
-
version = "0.1.
|
|
3
|
+
version = "0.1.5"
|
|
4
4
|
authors = [
|
|
5
5
|
{ name="Apleut", email="me@apleut.dev" },
|
|
6
6
|
]
|
|
@@ -22,6 +22,7 @@ dependencies = [
|
|
|
22
22
|
"pydantic",
|
|
23
23
|
"typer",
|
|
24
24
|
"rich",
|
|
25
|
+
"platformdirs",
|
|
25
26
|
]
|
|
26
27
|
|
|
27
28
|
license = "MIT"
|
|
@@ -42,4 +43,4 @@ requires = ["setuptools>=68"]
|
|
|
42
43
|
build-backend = "setuptools.build_meta"
|
|
43
44
|
|
|
44
45
|
[tool.setuptools.packages.find]
|
|
45
|
-
include = ["laminate*"]
|
|
46
|
+
include = ["laminate*"]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|