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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: laminate-cli
3
- Version: 0.1.3
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
- Place exactly one `.gguf` model file in:
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
- ```text
110
- models/
111
- └── your-model.gguf
112
- ```
110
+ Laminate looks for exactly one `.gguf` file in two places, in this order:
113
111
 
114
- [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.
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
- Laminate automatically finds and loads the model when it runs.
127
+ Create the folder if it doesn't already exist, and place your `.gguf` file inside.
117
128
 
118
- If the `models/` directory does not exist, or contains zero or multiple `.gguf` files, Laminate will stop and explain what needs to be fixed.
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
- Place exactly one `.gguf` model file in:
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
- ```text
86
- models/
87
- └── your-model.gguf
88
- ```
85
+ Laminate looks for exactly one `.gguf` file in two places, in this order:
89
86
 
90
- [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.
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
- Laminate automatically finds and loads the model when it runs.
102
+ Create the folder if it doesn't already exist, and place your `.gguf` file inside.
93
103
 
94
- If the `models/` directory does not exist, or contains zero or multiple `.gguf` files, Laminate will stop and explain what needs to be fixed.
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
- MODELS_DIR = Path(__file__).resolve().parent.parent / "models"
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
- if not MODELS_DIR.exists():
16
- raise LLMError(
17
- f"Models folder not found at {MODELS_DIR}. Create it and "
18
- "place a .gguf model file inside (see README for a "
19
- "recommended model and download link)."
20
- )
21
-
22
- gguf_files = list(MODELS_DIR.glob("*.gguf"))
23
-
24
- if not gguf_files:
25
- raise LLMError(
26
- f"No .gguf model file found in {MODELS_DIR}. Download a "
27
- "compatible model (see README) and place it in that folder."
28
- )
29
-
30
- if len(gguf_files) > 1:
31
- names = ", ".join(f.name for f in gguf_files)
32
- raise LLMError(
33
- f"Multiple .gguf files found in {MODELS_DIR} ({names}) - "
34
- "keep only one so Laminate knows which to load."
35
- )
36
-
37
- return gguf_files[0]
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
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
- Place exactly one `.gguf` model file in:
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
- ```text
110
- models/
111
- └── your-model.gguf
112
- ```
110
+ Laminate looks for exactly one `.gguf` file in two places, in this order:
113
111
 
114
- [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.
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
- Laminate automatically finds and loads the model when it runs.
127
+ Create the folder if it doesn't already exist, and place your `.gguf` file inside.
117
128
 
118
- If the `models/` directory does not exist, or contains zero or multiple `.gguf` files, Laminate will stop and explain what needs to be fixed.
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.
@@ -2,3 +2,4 @@ llama-cpp-python
2
2
  pydantic
3
3
  typer
4
4
  rich
5
+ platformdirs
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "laminate-cli"
3
- version = "0.1.3"
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