Getting Started
Go from zero to release notes in under two minutes.
Installation
Install Cullit globally or use it with npx — no install needed:
# Run without installing
npx cullit generate --from HEAD~10 --provider none
# Or install globally
npm install -g cullit
# Or with pnpm
pnpm add -g cullit
--provider none flag uses a built-in template engine — no AI key needed. Great for trying Cullit out.Your First Run
Navigate to any Git repository and run:
# Generate notes from the last 10 commits, no AI key required
cullit generate --from HEAD~10 --provider none
# Generate notes between two tags with AI
cullit generate --from v1.0.0 --to v1.1.0
# Auto-detect: uses the two most recent tags
cullit generate
Cullit collects commits, enriches with ticket context (if configured), runs them through AI, and outputs categorized release notes.
Pricing & Tiers
Cullit uses a CULLIT_API_KEY to unlock Pro features. Without a key, the free tier is fully functional for template-based notes.
| Feature | Free | Pro ($29/mo) |
|---|---|---|
Template engine (--provider none) | ✅ | ✅ |
| Publish to stdout & file | ✅ | ✅ |
cullit status & cullit tags | ✅ | ✅ |
| AI providers (Anthropic, OpenAI, Gemini, Ollama) | — | ✅ |
| Jira & Linear enrichment | — | ✅ |
| Slack, Discord & GitHub Release publishing | — | ✅ |
| GitHub Action with AI | — | ✅ |
To activate Pro, set your API key:
# In your shell or .env file
CULLIT_API_KEY=clt_your_key_here
Get your key at sales@cullit.io or visit cullit.io/pricing.
Configuration
Create a .cullit.yml in your project root. You can generate one interactively:
cullit init
Full config reference:
# .cullit.yml
ai:
provider: anthropic # anthropic | openai | gemini | ollama | openclaw | none
model: claude-sonnet-4-20250514 # optional: override default model
audience: developer # developer | end-user | executive
tone: professional # professional | casual | terse
categories: # customize change categories
- features
- fixes
- breaking
- improvements
- chores
source:
type: local # local (git) | jira | linear
enrichment: # enrich git commits with ticket data
- jira
- linear
publish:
- type: stdout
- type: file
path: RELEASE_NOTES.md
- type: slack
webhook_url: $SLACK_WEBHOOK_URL
- type: slack
webhook_url: $DISCORD_WEBHOOK_URL
jira:
domain: yourcompany.atlassian.net
# Set JIRA_EMAIL and JIRA_API_TOKEN in your environment
linear:
# Set LINEAR_API_KEY in your environment
AI Providers
Cullit supports six providers. Set the relevant API key in your environment:
| Provider | Env Variable | Default Model | Notes |
|---|---|---|---|
| Anthropic | ANTHROPIC_API_KEY | claude-sonnet-4-20250514 | Best quality. Recommended. |
| OpenAI | OPENAI_API_KEY | gpt-4o | Great alternative. |
| Gemini | GEMINI_API_KEY | gemini-2.5-flash | Google AI. |
| Ollama | OLLAMA_HOST (optional) | llama3.1 | Local inference. Free. Private. |
| OpenClaw | OPENCLAW_TOKEN | routes to best model | AI gateway / router. |
| none | — | built-in template | No AI key needed. Categorizes by conventional commits. |
cullit generate --from v1.0.0 --provider openai --model gpt-4o-miniEnvironment Variables
Cullit reads these from your shell or a .env file in the project root:
| Variable | Purpose |
|---|---|
CULLIT_API_KEY | Cullit Pro license key (enables AI, integrations, advanced publishing) |
ANTHROPIC_API_KEY | Anthropic API key |
OPENAI_API_KEY | OpenAI API key |
GEMINI_API_KEY | Gemini API key |
OLLAMA_HOST | Ollama server URL (default: http://localhost:11434) |
OPENCLAW_TOKEN | OpenClaw gateway auth token |
JIRA_EMAIL | Jira account email for API auth |
JIRA_API_TOKEN | Jira API token |
LINEAR_API_KEY | Linear API key |
SLACK_WEBHOOK_URL | Slack incoming webhook |
DISCORD_WEBHOOK_URL | Discord webhook |
GITHUB_TOKEN | GitHub token (auto-set in Actions) |
CLI Reference
cullit generate
Generate release notes from git commits, Jira issues, or Linear tickets.
| Flag | Short | Description | Default |
|---|---|---|---|
--from | -f | Start ref โ tag, branch, SHA, JQL, or Linear filter | Auto-detect (2nd latest tag) |
--to | -t | End ref โ tag, branch, or SHA | HEAD |
--provider | AI provider to use | From config or anthropic | |
--model | AI model override | Provider default | |
--format | Output format: markdown, html, json | markdown | |
--source | Source type: local, jira, linear | From config or local | |
--audience | Audience: developer, end-user, executive | From config or developer | |
--config | -c | Config file path | .cullit.yml |
--dry-run | Generate but don't publish | ||
--verbose | Show detailed output | ||
--quiet | Suppress non-error output |
# Between two tags
cullit generate --from v2.3.0 --to v2.4.0
# Last N commits, JSON output
cullit generate --from HEAD~15 --format json
# Executive summary with Gemini
cullit generate --from v1.0.0 --audience executive --provider gemini
# From Jira sprint
cullit generate --source jira --from "project = PROJ AND sprint = 'Sprint 42'"
# From Linear team
cullit generate --source linear --from "team:ENG"
# No AI key, template engine
cullit generate --from HEAD~5 --provider none
# Local Ollama
cullit generate --from v1.0.0 --provider ollama --model llama3.1
cullit status
Release readiness check. Analyzes unreleased commits and recommends whether it's time to release, what semver bump to use, and why.
cullit status
# Output:
Current version: v1.2.0
Suggested next: v1.3.0 (minor)
Last release: 12 day(s) ago
Unreleased commits: 8
Contributors: 3
Commit breakdown:
โจ Features: โโโโโโโโโโโโโโโโโโโโ 4
๐ Fixes: โโโโโโโโโโ 2
๐งน Chores: โโโโโ 1
๐ Other: โโโโโ 1
Should you release? ๐ข Yes โ time to release
Why:
โ 4 new feature(s) โ minor bump recommended
โ 8 commit(s) since v1.2.0 โ consider releasing
The advisor also runs automatically after cullit generate and nudges you when thresholds are met (suppressed in --quiet mode).
cullit init
Interactive config setup. Creates a .cullit.yml with your preferences:
cullit init
# Prompts for: provider, source, audience, tone, enrichment
# Creates .cullit.yml in the current directory
cullit tags
Lists recent git tags in the repository โ useful for finding the right --from ref:
cullit tags
Recent tags:
โ v2.4.0
v2.3.0
v2.2.1
v2.2.0
Integrations
GitHub Action
Add Cullit to your CI/CD pipeline with zero configuration:
# .github/workflows/release-notes.yml
name: Release Notes
on:
push:
tags: ['v*']
jobs:
release-notes:
runs-on: ubuntu-latest
permissions:
contents: write # for GitHub Release
steps:
- uses: actions/checkout@v5
with:
fetch-depth: 0 # full history for tag comparison
- uses: mttaylor/cullit@main
with:
provider: anthropic
audience: end-user
publish-github-release: 'true'
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Action inputs:
| Input | Description | Default |
|---|---|---|
from | Start ref (auto-detects previous tag if omitted) | previous tag |
to | End ref | HEAD |
provider | AI provider | anthropic |
model | AI model override | provider default |
audience | Target audience | developer |
tone | Writing tone | professional |
format | Output format | markdown |
publish-github-release | Create/update GitHub Release | false |
publish-slack-webhook | Slack webhook URL | |
publish-discord-webhook | Discord webhook URL | |
jira-domain | Jira domain for enrichment |
Jira Integration
Cullit can use Jira as a primary source (replace git) or as enrichment (add ticket context to git commits).
As primary source:
# Query completed issues by project
cullit generate --source jira --from PROJ
# By sprint
cullit generate --source jira --from "project = PROJ AND sprint = 'Sprint 42'"
# By fix version
cullit generate --source jira --from PROJ --to v2.0
As enrichment (adds Jira details to git commits):
# .cullit.yml
source:
type: local
enrichment: [jira]
jira:
domain: yourcompany.atlassian.net
Set JIRA_EMAIL and JIRA_API_TOKEN in your environment.
PROJ-123 from commit messages and enriches them with titles, descriptions, labels, and priority from the Jira API.Linear Integration
Works the same way — as a primary source or enrichment.
As primary source:
# By team
cullit generate --source linear --from "team:ENG"
# By project
cullit generate --source linear --from "project:Mobile App"
# By label
cullit generate --source linear --from "label:release-v2"
# Current cycle
cullit generate --source linear --from "cycle:current"
As enrichment:
# .cullit.yml
source:
type: local
enrichment: [linear]
Set LINEAR_API_KEY in your environment.
Publishing
Cullit publishes to multiple targets simultaneously. Configure in .cullit.yml.
stdout & File
publish:
- type: stdout # print to terminal
- type: file
path: RELEASE_NOTES.md # write to file
Slack
Create an incoming webhook in your Slack workspace, then:
publish:
- type: slack
webhook_url: $SLACK_WEBHOOK_URL
Cullit formats notes with emoji categories and Slack mrkdwn syntax.
Discord
Create a webhook in your Discord channel settings, then:
publish:
- type: discord
webhook_url: $DISCORD_WEBHOOK_URL
Posts as a rich embed with the Cullit accent color.
GitHub Release
Automatically creates or updates a GitHub Release. Works in GitHub Actions (uses GITHUB_TOKEN automatically):
publish:
- type: github-release
Advanced Usage
Library Usage
Use Cullit programmatically in your Node.js / TypeScript projects:
npm install @cullit/core @cullit/config
import { runPipeline, createLogger } from '@cullit/core';
import { loadConfig } from '@cullit/config';
const config = loadConfig();
const logger = createLogger('verbose');
const result = await runPipeline('v1.0.0', 'HEAD', config, {
format: 'markdown',
dryRun: true,
logger,
});
console.log(result.formatted); // the release notes string
console.log(result.notes.changes); // structured change entries
console.log(result.duration); // pipeline duration in ms
Packages:
| Package | Purpose |
|---|---|
cullit | CLI tool — npx cullit generate |
@cullit/core | Core engine: pipeline, collectors, generators, publishers |
@cullit/config | Config loader: YAML parsing, env var resolution, type exports |
Release Advisor
The release advisor analyzes your unreleased commits and recommends when to release:
import { analyzeReleaseReadiness } from '@cullit/core';
const advisory = analyzeReleaseReadiness();
console.log(advisory.shouldRelease); // true | false
console.log(advisory.suggestedBump); // 'patch' | 'minor' | 'major'
console.log(advisory.nextVersion); // 'v1.3.0'
console.log(advisory.reasons); // ['4 new features', '12 days since last release']
console.log(advisory.breakdown); // { features: 4, fixes: 2, breaking: 0, ... }
Heuristics that trigger a release recommendation:
- 5+ unreleased commits accumulated
- 3+ new features
- Any breaking changes
- Security-related commits (keywords: security, CVE, vulnerability)
- 14+ days since last release
API Server
Cullit includes a lightweight REST API for programmatic access:
# Start the server
node packages/api/dist/index.js
# Generate release notes
curl -X POST http://localhost:3000/generate \
-H "Content-Type: application/json" \
-d '{"from": "v1.0.0", "provider": "none"}'
Endpoints:
| Method | Path | Description |
|---|---|---|
GET | /health | Health check — version, uptime |
GET | /openapi.json | OpenAPI 3.1 specification |
POST | /generate | Generate release notes |
Configuration:
| Env Variable | Purpose | Default |
|---|---|---|
PORT | Server port | 3000 |
CULLIT_API_TOKEN | Bearer token for auth | disabled |
ALLOWED_ORIGINS | CORS allowed origins | * |
RATE_LIMIT | Requests per minute per IP | 30 |
Real-World Walkthrough
Here's exactly how you'd set up Cullit for a real project from scratch.
Scenario
You maintain a SaaS product called Acme Dashboard. Your team uses GitHub for code, Jira for project management, and Slack for comms. You want release notes auto-generated when you push a tag.
Step 1 — Install & Initialize
cd ~/projects/acme-dashboard
npm install -g cullit
cullit init
# Answer the prompts:
AI provider: anthropic
Source type: local
Audience: end-user
Tone: professional
Enrich from: jira
โ Created .cullit.yml
Step 2 — Configure Integrations
Edit the generated .cullit.yml:
ai:
provider: anthropic
audience: end-user # customer-facing notes
tone: professional
source:
type: local
enrichment: [jira] # pull ticket context
publish:
- type: stdout
- type: file
path: CHANGELOG.md
- type: slack
webhook_url: $SLACK_WEBHOOK_URL
jira:
domain: acme.atlassian.net
Step 3 — Set Environment Variables
# .env (add to .gitignore!)
ANTHROPIC_API_KEY=sk-ant-...
JIRA_EMAIL=matt@acme.com
JIRA_API_TOKEN=ATATT3x...
SLACK_WEBHOOK_URL=https://hooks.slack.com/services/T.../B.../...
Step 4 — Test Locally
# Preview notes from the last 5 commits (dry run)
cullit generate --from HEAD~5 --dry-run
# Check readiness
cullit status
# Full run between tags
cullit generate --from v2.3.0 --to v2.4.0
Step 5 — Automate with GitHub Actions
Create .github/workflows/release-notes.yml:
name: Release Notes
on:
push:
tags: ['v*']
permissions:
contents: write
jobs:
notes:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
with:
fetch-depth: 0
- uses: mttaylor/cullit@main
with:
provider: anthropic
audience: end-user
publish-github-release: 'true'
publish-slack-webhook: ${{ secrets.SLACK_WEBHOOK_URL }}
jira-domain: acme.atlassian.net
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
JIRA_EMAIL: ${{ secrets.JIRA_EMAIL }}
JIRA_API_TOKEN: ${{ secrets.JIRA_API_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Step 6 — Ship a Release
# Check if it's time to release
cullit status
# Tag and push
git tag v2.4.0
git push origin v2.4.0
# GitHub Actions fires automatically:
# โ Collects commits v2.3.0..v2.4.0
# โ Enriches with Jira ticket data
# โ Generates AI-powered release notes
# โ Creates GitHub Release
# โ Posts to #releases in Slack
What You Get
A GitHub Release and Slack message that looks like this:
## Release v2.4.0 โ March 13, 2026
This release introduces real-time collaboration, new export
formats, and several performance improvements.
โจ Features
- Real-time collaboration for shared dashboards (DASH-142)
- Export API now supports CSV and PDF formats (DASH-156)
- Webhook configuration UI with test-send (DASH-161)
๐ Bug Fixes
- Fixed timezone rendering in scheduled reports (DASH-149)
- Resolved memory leak in WebSocket pool (DASH-155)
โ ๏ธ Breaking Changes
- /api/v1/export deprecated, use /api/v2/export (DASH-160)
audience modes produce different output from the same data.Cullit is open source under the MIT license. View on GitHub • npm • Home