npm package: @sachinthapa572/lazycommit
Description: Writes your git commit messages for you with AI providers
Author: Sachin Thapa
Latest version: 1.3.7

<div align="center">
  <div>
    <h1 align="center">lazycommit</h1>
<img width="2816" height="1536" alt="lazycommit" src="https://github.com/user-attachments/assets/ee0419ef-2461-4b45-8509-973f3bb0f55c" />

  </div>
   <p>A CLI that writes your git commit messages for you with AI providers. Never write a commit message again.</p>

</div>

---

## Setup

> The minimum supported version of Node.js is v18. Check your Node.js version with `node --version`.

### Prerequisites

- Git installed and available in your PATH
- Node.js `>=18`

### Install

Install _lazycommit_ globally:

```sh
npm install -g @sachinthapa572/lazycommit
```

### Upgrading

Check the installed version with:

```
lazycommit --version
```

If it's not the [latest version](https://github.com/sachinthapa572/lazycommit/releases/latest), run:

```sh
npm update -g @sachinthapa572/lazycommit
```

#### Automatic Update Notifications

lazycommit automatically checks for updates once per day and notifies you when a new version is available:

```sh
lazycommit
# Output when update available:
# 📦 Update available: v1.2.4 → v1.3.0
# Run: npm install -g @sachinthapa572/lazycommit@latest
```

You can disable this feature with:

```sh
lazycommit config set update-check-enabled=false
```

#### Manual Version Check

To check for updates immediately (bypassing the daily cache):

```sh
lazycommit --version-check
```

This is useful for testing or when you want to force an update check regardless of when the last check occurred.

## Usage

### CLI mode

You can call `lazycommit` directly to generate a commit message for your staged changes:

```sh
git add <files...>
lazycommit
```

`lazycommit` passes unknown flags to `git commit`, so you can pass [`commit` flags](https://git-scm.com/docs/git-commit).

For example, you can stage all changes in tracked files as you commit:

```sh
lazycommit --all # or -a
```

> 👉 **Tip:** Use the `lzc` alias if `lazycommit` is too long for you.

#### Generate multiple recommendations

Sometimes the recommended commit message isn't the best so you want it to generate a few to pick from. You can generate multiple commit messages at once by passing in the `--generate <i>` flag, where 'i' is the number of generated messages:

```sh
lazycommit --generate <i> # or -g <i>
```

> Warning: this uses more tokens, meaning it costs more.

#### Generating Conventional Commits

If you'd like to generate [Conventional Commits](https://conventionalcommits.org/), you can use the `--type` flag followed by `conventional`. This will prompt `lazycommit` to format the commit message according to the Conventional Commits specification:

```sh
lazycommit --type conventional # or -t conventional
```

This feature can be useful if your project follows the Conventional Commits standard or if you're using tools that rely on this commit format.

#### Review, edit, and confirm messages

Lazycommit now lets you review the generated message, optionally edit it, and then confirm before it is committed.

- You'll see a menu: Use as-is, Edit, or Cancel
- If you choose Use as-is, it commits immediately without additional prompts
- If you choose Edit, you can modify the message; then you'll be asked to confirm the final message before committing

Example (single commit):

```sh
git add .
lazycommit
# Review generated commit message:
#   feat: add lazycommit command
# → Choose "Use as-is" to commit immediately
# → Or choose "Edit" to modify, then confirm the final message before commit
```

#### Exclude files from analysis

You can exclude specific files from AI analysis using the `--exclude` flag:

```sh
lazycommit --exclude package-lock.json --exclude dist/
```

#### Using `.lazycommitignore` file

For persistent, repository-level file exclusions, create a `.lazycommitignore` file in your repository root. This file works similarly to `.gitignore`, allowing you to define patterns for files that should always be excluded from AI analysis.

**Creating the file:**

```sh
# Create .lazycommitignore in your repository root
touch .lazycommitignore
```

**Format:**

The `.lazycommitignore` file uses a simple format:

- One pattern per line
- Supports glob patterns (`*`, `**`, etc.)
- Lines starting with `#` are treated as comments
- Empty lines are ignored

**Example `.lazycommitignore`:**

```gitignore
# Build outputs
dist/
build/
.next/
out/

# Dependencies
node_modules/
vendor/

# Generated files
*.min.js
*.min.css
*.bundle.js

# Lock files (usually don't need AI analysis)
package-lock.json
yarn.lock
pnpm-lock.yaml

# IDE and editor files
.vscode/
.idea/

# Environment and secrets
.env
.env.*
*.pem

# Test coverage
coverage/
.nyc_output/

# Logs
*.log
```

**How it works:**

- Patterns are applied automatically to all `lazycommit` runs in the repository
- Works alongside `--exclude` flags (both are combined)
- Patterns use gitignore-style syntax for excluding files and directories
- The file is repository-specific and can be committed to version control

**Precedence:**

Both `.lazycommitignore` patterns and `--exclude` flags are applied together, so you can use `.lazycommitignore` for common exclusions and `--exclude` for one-time exclusions:

```sh
# Excludes everything in .lazycommitignore PLUS temp files for this run
lazycommit --exclude "*.tmp" --exclude "scratch/"
```

#### Include commit history for style consistency

You can include recent commit history in the AI prompt to generate messages that match your project's commit style:

```sh
lazycommit --history
```

This includes recent commit messages as context, helping the AI match your project's style and conventions. You can customize how many commits to include:

```sh
lazycommit --history --history-count 5
```

You can also disable history if it's enabled in your config:

```sh
lazycommit --no-history
```

#### One-time guidance override (single run)

You can pass one-time advisory guidance with `--guidance-prompt`:

```sh
lazycommit --guidance-prompt "Prefer concise verbs and mention auth subsystem"
```

Behavior:

- Applies only to the current run.
- Overrides `guidance-prompt` from config for that run.
- Passing an empty value clears guidance for that run.
- Does not persist unless you set it through `lazycommit config set`.

Safety behavior:

- Guidance is advisory only (style preference).
- Output must still follow commit format, be diff-grounded, and remain relevant.
- Prompt hijacking attempts or unrelated instructions are ignored.

#### Version Check

To manually check for updates immediately:

```sh
lazycommit --version-check
```

This bypasses the daily cache and checks for the latest version immediately. Useful for testing or when you want to force an update check.

#### Dry-run mode

Preview the generated commit message without actually committing:

```sh
lazycommit --dry-run
```

This is useful for:

- Testing how lazycommit would commit your changes
- CI/CD pipelines that need to preview messages
- Verifying commit message quality before automation

The generated message will be displayed but no commit is made.

#### Handling large diffs

For large commits with many files, lazycommit automatically stays within API limits and generates relevant commit messages:

- **Smart summarization**: Uses `git diff --cached --numstat` to create compact summaries of all changes
- **Context snippets**: Includes truncated diff snippets from top changed files for better context
- **Token-safe processing**: Keeps prompts small while maintaining accuracy for 20+ file changes
- **Single commit**: Always generates one commit message, no matter how many files are staged
- **Enhanced analysis**: Uses improved prompts and smart truncation for better commit message quality

### Git hook

You can also integrate _lazycommit_ with Git via the [`prepare-commit-msg`](https://git-scm.com/docs/githooks#_prepare_commit_msg) hook. This lets you use Git like you normally would, and edit the commit message before committing. The hook uses the same enhanced analysis and quality improvements as the CLI mode.

#### Install

In the Git repository you want to install the hook in:

```sh
lazycommit hook install
```

#### Uninstall

In the Git repository you want to uninstall the hook from:

```sh
lazycommit hook uninstall
```

#### Usage

1. Stage your files and commit:

   ```sh
   git add <files...>
   git commit # Only generates a message when it's not passed in
   ```

### Local pre-commit lint + format checks

If you want every commit to automatically format and lint staged files (and block commit on lint errors), this repo includes a pre-commit hook under `.githooks/pre-commit`.

Enable it once per local clone:

```sh
bun run hooks:install
```

What it does on each `git commit`:

- Runs `oxfmt` on staged, supported files
- Runs `oxlint --fix` on staged JS/TS files
- Runs `oxlint` to fail the commit if lint errors remain
- Re-stages updated files automatically

  > If you ever want to write your own message instead of generating one, you can simply pass one in: `git commit -m "My message"`

2. Lazycommit will generate a high-quality commit message using the same enhanced analysis as the CLI mode and pass it back to Git. Git will open it with the [configured editor](https://docs.github.com/en/get-started/getting-started-with-git/associating-text-editors-with-git) for you to review/edit it.

3. Save and close the editor to commit!

## Configuration

### Environment Variables (Recommended for API Keys)

For better security, especially when committing to version control, it's recommended to use environment variables for API keys instead of storing them in the config file.

1. **Create a `.env` file** (copy from `.env.example`):

   ```bash
   cp .env.example .env
   ```

2. **Add your API keys to `.env`**:

   ```bash
   # Groq API Key
   GROQ_API_KEY=gsk_your_groq_api_key_here

   # Cerebras API Key
   CEREBRAS_API_KEY=cb_your_cerebras_api_key_here

   # OpenRouter API Key
   OPENROUTER_API_KEY=sk-or-v1-your_openrouter_api_key_here
   ```

3. **Never commit `.env`** - it's already in `.gitignore`

**Priority Order**: lazycommit checks for API keys in this order:

1. Environment variables (highest priority)
2. Config file values (fallback)

This approach keeps your API keys secure while allowing you to commit configuration files to version control.

### Config File Structure

```json
{
	"activeProvider": "groq",
	"global": {
		"generate": 1,
		"locale": "en",
		"timeout": 10000,
		"max-length": 100,
		"type": "",
		"signup-message": "",
		"history-enabled": false,
		"history-count": 3,
		"guidance-prompt": "",
		"update-check-enabled": true
	},
	"preference": {
		"ascii-logo-enabled": true,
		"ask-to-push": false
	},
	"providers": {
		"groq": {
			"apiKey": "", // Leave empty when using environment variables
			"model": "openai/gpt-oss-120b",
			"customModels": []
		},
		"cerebras": {
			"model": "qwen-3-235b-a22b-instruct-2507",
			"customModels": []
		},
		"openrouter": {
			"model": "openrouter/free",
			"customModels": []
		},
		"github": {
			"model": "gpt-5-mini",
			"customModels": []
		}
	}
}
```

### JSON schema auto-suggestions

`lazycommit` now writes a `$schema` entry into `~/.lazycommit/config.json`, pointing to:

```text
https://raw.githubusercontent.com/sachinthapa572/lazycommit/main/src/schema/config-schema.json
```

This enables editor IntelliSense/autocomplete, inline docs, and validation for config keys and values when editing the config file.

If your editor does not automatically pick this up, add a JSON schema mapping (example for VS Code):

```json
{
	"json.schemas": [
		{
			"fileMatch": ["*/.lazycommit/config.json", ".lazycommit/config.json"],
			"url": "https://raw.githubusercontent.com/sachinthapa572/lazycommit/main/src/schema/config-schema.json"
		}
	]
}
```

### Guided setup (first-time)

Run:

```sh
lazycommit config
```

You can also run the explicit setup mode:

```sh
lazycommit config setup
```

This opens a step-by-step setup flow for:

- provider
- provider API key
- model
- generate
- locale
- proxy
- timeout
- max-length
- type
- signup-message
- history-enabled
- history-count
- guidance-prompt
- update-check-enabled

At the end, lazycommit saves your config and prints the updated values.

### Interactive change mode

To update settings later through a menu:

```sh
lazycommit config change
```

This lists all editable settings, lets you choose one, prompts for a new value, saves it, and shows the updated config.

### Reading a configuration value

To retrieve a configuration option, use the command:

```sh
lazycommit config get <key>
```

For example, to retrieve the API key, you can use:

```sh
lazycommit config get GROQ_API_KEY
```

You can also retrieve multiple configuration options at once by separating them with spaces:

```sh
lazycommit config get GROQ_API_KEY generate
```

To display all current configuration settings in a readable format, use:

```sh
lazycommit config show
```

### Setting a configuration value

To set a configuration option, use the command:

```sh
lazycommit config set <key>=<value>
```

For example, to set the API key, you can use:

```sh
lazycommit config set GROQ_API_KEY=<your-api-key>
```

You can also set multiple configuration options at once by separating them with spaces, like

```sh
lazycommit config set GROQ_API_KEY=<your-api-key> generate=3 locale=en
```

### Options

> Note: `generate` supports values from `1` to `10`. Higher values increase API token costs.

#### GROQ_API_KEY

Required

The Groq API key.
Get it from https://console.groq.com/keys.

#### CEREBRAS_API_KEY

Required when `provider=cerebras`

The Cerebras API key.
Get it from https://cloud.cerebras.ai.

#### OPENROUTER_API_KEY

Required when `provider=openrouter`

The OpenRouter API key.
Get it from https://openrouter.ai/settings/keys.

#### provider

Default: `groq`

Provider used to generate commit messages.

Supported values:

- `groq`
- `cerebras`
- `openrouter`
- `github`

Examples:

```sh
lazycommit config set provider=github
lazycommit config set provider=groq
lazycommit config set provider=cerebras
lazycommit config set provider=openrouter
```

When switching providers, lazycommit automatically resets `model` to that provider's default if the current model is incompatible.

#### locale

Default: `en`

The locale to use for the generated commit messages. Consult the list of codes in: https://wikipedia.org/wiki/List_of_ISO_639-1_codes.

#### generate

Default: `1`

The number of commit messages to generate to pick from. Valid range: `1` to `10`.

Note, this will use more tokens as it generates more results, meaning higher API costs.

```sh
lazycommit config set generate=3
```

#### proxy

Set a HTTP/HTTPS proxy to use for requests.

To clear the proxy option, you can use the command (note the empty value after the equals sign):

```sh
lazycommit config set proxy=
```

#### model

Default: depends on `provider`

The model to use for generating commit messages.

Available models by provider:

- `groq`:
- `openai/gpt-oss-120b` (default)
- `moonshotai/kimi-k2-instruct-0905`
- `moonshotai/kimi-k2-instruct`
- `groq/compound`
- `groq/compound-mini`
- `cerebras`:
- `qwen-3-235b-a22b-instruct-2507` (default)
- `llama3.1-8b`
- `openrouter`:
- `openrouter/free` (default)
- `github`:
- `gpt-5-mini` (default)
- `gpt-5.4-mini`
- `gpt-4o-mini-2024-07-18`

Example:

```sh
lazycommit config set provider=github model=gpt-5.4-mini
lazycommit config set CEREBRAS_API_KEY=<your-api-key> provider=cerebras model=qwen-3-235b-a22b-instruct-2507
lazycommit config set OPENROUTER_API_KEY=<your-api-key> provider=openrouter model=openrouter/free
```

#### timeout

The timeout for provider requests in milliseconds.

Default: `10000` (10 seconds)

```sh
lazycommit config set timeout=20000 # 20s
```

#### max-length

The maximum character length of the generated commit message.

Default: `100`

```sh
lazycommit config set max-length=150
```

#### type

Default: `""` (Empty string)

The type of commit message to generate. Set this to "conventional" to generate commit messages that follow the Conventional Commits specification:

```sh
lazycommit config set type=conventional
```

You can clear this option by setting it to an empty string:

```sh
lazycommit config set type=
```

#### guidance-prompt

Default: `""` (Empty string)

Optional advisory style guidance for commit message generation.

This value helps steer style preferences (for example: wording nuances, subsystem keywords, or verbosity), but it is treated as **soft guidance only**.

Safety behavior and precedence:

- It does **not** override core commit constraints.
- Messages must remain grounded in staged diff context.
- Conflicting, invalid-format, or irrelevant guidance is ignored.
- Max length: `1000` characters.
- Whitespace-only values are normalized to empty (feature off).

Example:

```sh
lazycommit config set guidance-prompt="Prefer concise verbs and include subsystem keywords when relevant"
```

To clear it:

```sh
lazycommit config set guidance-prompt=
```

#### signup-message

Default: `""` (Empty string)

Optional sign-off identity to append at the end of generated messages.

If set, lazycommit instructs the AI to end with:

```text
--
Signed-off-by: <signup-message>
```

Example:

```sh
lazycommit config set signup-message="Sachin Thapa <contactsachin572@gmail.com>"
```

#### history-enabled

Default: `false`

Whether to include recent commit history in the AI prompt for generating commit messages that match your project's style.

```sh
lazycommit config set history-enabled=true
```

Including history helps the AI understand your project's commit message conventions and style, leading to more consistent suggestions.

#### history-count

Default: `3`

The number of recent commit messages to include when `history-enabled` is true. Valid range: `2` to `10`.

```sh
lazycommit config set history-count=5
```

This setting only takes effect when history is enabled.

#### update-check-enabled

Default: `true`

Whether to automatically check for updates once per day when running lazycommit.

```sh
lazycommit config set update-check-enabled=false
```

When enabled, lazycommit will check for updates periodically and notify you when a new version is available. The check is limited to once per day to avoid excessive network requests.

## How it works

This CLI tool runs `git diff` to grab all your latest code changes, then sends them to the configured provider model and returns AI-generated commit messages.

Provider behavior:

- `groq` uses Groq API with `GROQ_API_KEY`
- `github` uses GitHub Copilot SDK and your local Copilot CLI login session (`copilot auth login`)

### Large diff handling (automatic)

For large commits that exceed API token limits, lazycommit automatically:

1. **Detects large/many-file diffs** and switches to enhanced analysis mode
2. **Creates compact summaries** using `git diff --cached --numstat` to capture all changes efficiently
3. **Includes context snippets** from the most changed files to provide semantic context
4. **Generates a single commit message** that accurately reflects all changes without hitting API limits
5. **Smart truncation** preserves sentence structure and meaning when messages approach length limits
6. **Enhanced prompts** provide better context for AI to generate complete, professional commit messages

This ensures you can commit large changes (like new features, refactoring, or initial project setup) without hitting API limits, while maintaining accuracy, relevance, and high-quality commit messages.

## Troubleshooting

### "Request too large" error (413)

If you get a 413 error, your diff is too large for the API. Try these solutions:

1. **Exclude build artifacts**:

   ```sh
   lazycommit --exclude "dist/**" --exclude "node_modules/**" --exclude ".next/**"
   ```

2. **Create a `.lazycommitignore` file** for persistent exclusions:

   ```gitignore
   # .lazycommitignore
   dist/
   node_modules/
   .next/
   *.min.js
   package-lock.json
   ```

3. **Use a different model**:

   ```sh
   lazycommit config set model=groq/compound-mini
   ```

4. **Commit in smaller batches**:
   ```sh
   git add src/  # Stage only source files
   lazycommit
   git add docs/ # Then stage documentation
   lazycommit
   ```

### No commit messages generated

- Check provider settings: `lazycommit config show`
- For `groq`, verify `GROQ_API_KEY` is set
- For `github`, ensure `copilot` CLI is installed and run `copilot auth login`
- Verify you have staged changes: `git status`
- Try excluding large files or using a different model

### Slow performance with large diffs

- **Use the default model**: `lazycommit config set model=openai/gpt-oss-120b`
- Exclude unnecessary files: `lazycommit --exclude "*.log" --exclude "*.tmp"` or use `.lazycommitignore`
- Use the built-in large diff handling for better context and accuracy
- Lower generate count: `lazycommit config set generate=1` (default)
- Reduce timeout: `lazycommit config set timeout=5000` for faster failures
- **Transient errors are retried automatically**: Rate limits (429) and service timeouts (503/504) are automatically retried with exponential backoff

## Why lazycommit?

- **Fast workflow**: Generate commit messages directly from staged changes
- **Provider choice**: Use Groq, GitHub Copilot, Cerebras, or OpenRouter
- **Works for large commits**: Built-in compact summaries and context snippets
- **Flexible output**: Generate one or multiple suggestions and edit before committing
- **Resilient**: Automatic retry with exponential backoff for transient errors
- **Repository-level config**: `.lazycommitignore` for persistent file exclusions
- **Dry-run support**: Preview messages before committing with `--dry-run`

## Maintainers

- **Sachin Thapa**: [@sachinthapa572](https://github.com/sachinthapa572)
- **Kshitiz Sharma (imxitiz)**: [@imxitiz](https://github.com/imxitiz)

## License

This project is licensed under the Apache-2.0 License - see the [LICENSE](LICENSE) file for details.