Skip to main content
Laminate Logo

Laminate

My Website · Changelog


A CLI that turns your Git history into release-ready changelogs using a local LLM.

Instead of manually sorting hundreds of commits into Added, Changed, Fixed, and other categories, Laminate reads your Git history, interprets the changes, and generates a clean Keep a Changelog compatible document.

Features

  • 🤖 Local LLM processing — your Git history stays on your machine
  • 📝 Release-ready Markdown — generates structured changelogs
  • 🗂️ Automatic categorization — sorts changes into standard changelog categories
  • 🧩 Related-commit grouping — combines related commits into a single entry
  • 📦 Batch processing — process large repositories without sending the entire history to the model at once
  • 🔒 No API keys required — Laminate uses a local GGUF model through llama-cpp-python
  • 🛠️ Git-aware filtering — filter commits by date or Git commit range
  • 🚀 Release support — generate either an [Unreleased] section or a versioned release

Installation

PyPI

Install Laminate with pip:

pip install laminate-cli

Note: The PyPI package is named laminate-cli, while the command and Python package are named laminate.

From source

Clone the repository and install it locally:

git clone https://github.com/Apleut/Laminate.git
cd Laminate
pip install .

For development:

pip install -e .

Windows

llama-cpp-python may require a pre-built CPU wheel on Windows.

Install it first with:

pip install llama-cpp-python --extra-index-url https://abetlen.github.io/llama-cpp-python/whl/cpu

Then install Laminate:

pip install .

Model

Laminate runs a local GGUF model using llama-cpp-python.

Place exactly one .gguf model file in:

models/
└── your-model.gguf

Phi-4-mini-instruct is a good pick, and is the model used for Laminate's development.

Laminate automatically finds and loads the model when it runs.

If the models/ directory does not exist, or contains zero or multiple .gguf files, Laminate will stop and explain what needs to be fixed.

The model is intentionally kept separate from the package because GGUF models can be large and have different licensing requirements.

Usage

From inside a Git repository:

laminate

Laminate will read the repository's commit history, categorize the changes, and write the result to:

CHANGELOG.md

For example:

Reading commits from working directory...
Found 42 commits. Categorizing with the local model...
[categorize] processing batch 1/3 (20 commits)...
[categorize] processing batch 2/3 (20 commits)...
[categorize] processing batch 3/3 (2 commits)...

Done. Changelog written to CHANGELOG.md

Options

--repo

Specify the Git repository to read.

laminate --repo ./my-project

Defaults to the current working directory.

--since

Only include commits after a specific date.

laminate --since 2026-01-01

--until

Only include commits before a specific date.

laminate --until 2026-10-01

--range

Process a specific Git commit range.

laminate --range v1.0.0..v1.1.0

--range overrides --since and --until.

This is particularly useful when generating a changelog for a release.

--output

Choose where the generated changelog should be written.

laminate --output RELEASE_NOTES.md

Defaults to:

CHANGELOG.md

--batch-size

Control how many commits are sent to the model at once.

laminate --batch-size 25

Larger batches can provide more context to the model, while smaller batches can reduce the amount of context required for each request.

--release

Generate a versioned release section instead of an [Unreleased] section.

laminate --release 1.1.0

The resulting header will look like:

## [1.1.0] - 2026-10-03

Without --release, Laminate generates:

## [Unreleased]

Example

Suppose your repository contains commits like:

Add user authentication
Fix crash when configuration is missing
Refactor authentication middleware
Remove deprecated login endpoint
Add password reset flow

Instead of producing one entry for every commit, Laminate can turn them into something like:

# Changelog

All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog
and this project adheres to Semantic Versioning.

## [Unreleased]

### Added

- Added user authentication and password reset functionality.

### Changed

- Refactored the authentication middleware.

### Removed

- Removed the deprecated login endpoint.

### Fixed

- Fixed a crash caused by missing configuration.

The exact output depends on the Git history and the model being used.

Supported Categories

Laminate currently uses the standard Keep a Changelog categories:

  • Added
  • Changed
  • Deprecated
  • Removed
  • Fixed
  • Security

Categories that contain no changes are omitted from the final document.

Privacy

Laminate is designed around local processing.

Your Git history is passed to the LLM running on your own machine. Laminate does not require an OpenAI, Anthropic, or other hosted AI API.

The model you download and use is subject to its own license and terms.

Contributing

Contributions, bug reports, and ideas are welcome.

If you find a problem with Laminate, please open an issue with:

  • What you were trying to do
  • The command you ran
  • The relevant error message
  • Your Python version
  • Your operating system

Or email me at me@apleut.dev.

For changes to Laminate itself, pull requests are welcome.

License

License information will be added before the first stable release.

Metadata

Release files for laminate-cli 0.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for laminate-cli 0.1.1
File Size Uploaded
laminate_cli-0.1.1.tar.gz 24.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for laminate-cli 0.1.1
File Interpreter ABI Platform
laminate_cli-0.1.1-py3-none-any.whl Python 3 none any Details

Total release size: 48.6 kB

Release files / laminate_cli-0.1.1.tar.gz

Download URL laminate_cli-0.1.1.tar.gz
Size 24.3 kB
Tags Source
SHA-256 checksum
How to use checksums
9cce19e1dde433cf10f69b6688231d8839eb543d5450d8ae0b56009ff370b332
BLAKE2b-256 checksum
How to use checksums
efa4d2b41205cc00ef2fa4ac1ba92929c8fb7ada119a5719c65b01b2f0f1b01c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 3, 2026.

Transparency log

Release files / laminate_cli-0.1.1-py3-none-any.whl

Download URL laminate_cli-0.1.1-py3-none-any.whl
Size 24.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d197831ddc51ccc9b8fd4c870e701d29116c730442a22e54c9243884fc09f6ab
BLAKE2b-256 checksum
How to use checksums
ba026ecfbabbbb86c0f51e66cae58f2971337620754cac7eb43d53387e2b4cf3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 3, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page