npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@luctst/commai

v0.1.1

Published

Generate git commit messages using AI

Downloads

12

Readme

commai

Generate git commit messages using AI — the only dependency-light, hook-chain-compatible tool that doesn't stomp on your workflow.

npm CI License

Why commai?

  • 2 production dependencies. No bloat. Competitors ship 12–20+ transitive deps; commai ships chalk and commander.
  • Hook chain compatible. Works with husky, commitlint, .git/hooks/. Most tools overwrite your hooks; commai chains to them.
  • AI errors don't block. Network timeout? API down? Exit 0. Your commit proceeds. No friction.
  • Multi-provider. Claude and OpenAI. Model name tells us which API to hit—setup is automatic, no provider config wiring.
  • Native fetch, no SDKs. Explicit HTTP calls over bloated SDK clients. Fast, predictable, lean.

Installation

Requires Node 18+.

# Global (recommended)
npm install -g @luctst/commai

# Per-project
npm install --save-dev @luctst/commai
pnpm add -D @luctst/commai

Quick Start

1. Set API key

# Claude (Anthropic)
export ANTHROPIC_API_KEY=sk-ant-...

# OpenAI
export OPENAI_API_KEY=sk-...

Or store in ~/.commai/.env or .env (project root) to persist across sessions. Shell environment always takes precedence. See Environment Variables for details.

2. Install hook (per repo)

cd your-project
commai install --model sonnet@latest

Stores config to .commai/.config, chains to husky/.git/hooks/, sets core.hooksPath.

3. Make a commit

git add .
git commit

Interactive prompt:

Generated commit message:
────────────────────────────────────────
feat: add user authentication
────────────────────────────────────────

  (a) Accept
  (r) Regenerate
  (c) Cancel

>
  • a — Accept and write the message to your commit
  • r — Regenerate with optional custom instructions
  • c — Cancel; edit the message manually and retry

Graceful: No staged changes? User message already typed? Merge/amend context? commai exits early without generating. Your workflow, uninterrupted.


Why commai? (Detailed)

Minimal Dependencies

Most AI commit tools pull in 12–20+ transitive packages. commai uses two: chalk (color output) and commander (CLI parsing). That's it.

Why it matters: smaller attack surface, faster installs, fewer breakage vectors when deps update.

Hook Chain Compatibility

Your repo likely already has hooks. husky, commitlint, custom scripts in .git/hooks/. commai chains to them instead of replacing:

.commai/prepare-commit-msg
  ├─ Run `commai generate`
  ├─ Then check `.husky/prepare-commit-msg`
  └─ Then check `.git/hooks/prepare-commit-msg`

If commai isn't installed, those tools still run. If you uninstall commai, they continue working. No cleanup, no breakage.

AI Errors Don't Block Commits

Network timeout? API rate-limit? Invalid key? commai logs the error and exits 0. Your commit still proceeds. You're never stuck.

This is intentional. AI is best-effort—comments, linting, tests all block commits; message generation shouldn't.

Multi-Provider Out of the Box

Pass --model sonnet@latest or --model gpt-4-turbo. commai infers the provider from the model name:

  • sonnet, haiku, opus → Anthropic API
  • gpt, o → OpenAI API

No separate config, no API URL wiring, no provider plugins. The model string tells us everything.

Native Fetch, Not SDKs

commai uses fetch directly instead of @anthropic-sdk/sdk or openai. Fewer layers, explicit HTTP, faster debugging. You can read the source and understand exactly what's hitting the API.


Configuration

Environment Variables

Only the key for your chosen provider is required. commai infers the provider from the model family in --model.

| Variable | Required for | Description | | ------------------- | ------------- | ----------------------------------------------------------------------------------------- | | ANTHROPIC_API_KEY | Claude models | Anthropic API key (starts with sk-ant-). Get one here. | | OPENAI_API_KEY | OpenAI models | OpenAI API key (starts with sk-). Get one here. |

.env File Loading

commai loads environment variables in this order (highest to lowest precedence):

  1. Shell environment — always wins, takes absolute precedence
  2. .env in your project root — project-specific overrides
  3. ~/.commai/.env — global fallback (lowest precedence)

Example ~/.commai/.env (global, covers all your projects):

ANTHROPIC_API_KEY=sk-ant-abc123...
OPENAI_API_KEY=sk-xyz789...

Example .env in project root (overrides global, never commit to git):

ANTHROPIC_API_KEY=sk-ant-project-specific...

Commands

commai install --model <model> [--interactive] [--auto-commit]

Install the prepare-commit-msg hook and write the runtime config to .commai/.config.

commai install --model sonnet@latest
commai install --model haiku@latest --interactive --auto-commit

Options:

| Flag | Default | Description | | ----------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------ | | --model <model> | Required | Model to use, in <family>@<version> format (e.g., sonnet@latest, [email protected]). See Model Selection. | | --interactive | true | Enable the accept/regenerate/cancel prompt on each commit. Pass --interactive=false to disable. | | --auto-commit | false | Run git commit -m '<message>' automatically after accepting. Pass --auto-commit to enable. |

Effects:

  • Creates .commai/ directory at repo root
  • Writes .commai/prepare-commit-msg (marked with # managed-by-commai)
  • Writes .commai/.config (JSON) with model, interactive, autoCommit, and the previous core.hooksPath value
  • Sets git config core.hooksPath .commai
  • Creates forwarder scripts for all 12 git hooks (chains to .husky/ and .git/hooks/)

To change options (e.g., switch model), re-run commai install --model <new-model>. Do not edit .commai/.config manually — the install command will overwrite your changes.

Idempotent: Running install again safely overwrites the hook if it was created by commai. Exits 1 if .commai/ exists but wasn't created by commai (foreign directory — refuses to overwrite).

commai uninstall

Remove the commai hook from the current repository.

commai uninstall

Effects:

  • Removes .commai/ directory entirely
  • Restores core.hooksPath to its previous value, or unsets it if it was previously empty
  • Preserves user's .husky/ and .git/hooks/ directories

Safety: Checks for the # managed-by-commai marker in .commai/prepare-commit-msg. Exits 1 if the marker is absent (refuses to uninstall a foreign hook directory).

commai generate <file>

Generate a commit message from staged changes. Normally called by the prepare-commit-msg hook; rarely invoked directly.

Arguments:

  • <file> — Path to the commit message file (usually .git/COMMIT_EDITMSG, provided by git)

All runtime options (model, interactive, autoCommit) are read from .commai/.config. To change them, re-run commai install --model <model> [--interactive] [--auto-commit].

Example:

commai generate .git/COMMIT_EDITMSG

Exit codes:

  • 0 — Success, or any expected failure (AI error, network timeout, user cancelled, early exits). Commit is never blocked.
  • 1 — Configuration error only (missing API key, commai install not run, not a git repo, unknown model family).

Model Selection

Alias Format

Models are specified as <family>@<version>. The family determines both the provider and the model series. Raw model IDs are also accepted.

Claude (Anthropic):

| Alias | Description | | ---------------------------- | ------------------------------------------ | | sonnet@latest | Latest Claude Sonnet — best quality | | haiku@latest | Latest Claude Haiku — fastest and cheapest | | opus@latest | Latest Claude Opus — highest capability | | [email protected] | Specific Claude version | | claude-3-5-sonnet-20241022 | Raw model ID |

OpenAI:

| Alias | Description | | ------------- | ---------------------------------------- | | gpt@latest | Latest GPT model | | o@latest | Latest OpenAI reasoning model (o-series) | | gpt@4-turbo | Specific GPT version | | gpt-4-turbo | Raw model ID |

Provider Auto-Detection

The provider is resolved from the model family — no extra config needed:

| Family | Provider | API key required | | ------------------------- | ------------------ | ------------------- | | sonnet, haiku, opus | Claude (Anthropic) | ANTHROPIC_API_KEY | | gpt, o | OpenAI | OPENAI_API_KEY |

How Resolution Works

  1. Extract the family from <family>@<version> (or scan the raw ID for a known family substring)
  2. Look up the provider from the family map above
  3. If the model is an alias (contains @), query the provider's models.list() API and filter by family (case-insensitive)
  4. If version is latest, pick the most recently created match; otherwise match by exact version
  5. If the model is a raw ID (no @), use it as-is without an API call
  6. Fall back to the input as-is if no match is found or the API call fails

Available Models

Claude:

curl https://api.anthropic.com/v1/models \
  -H "api-key: $ANTHROPIC_API_KEY" | jq '.data[].id'

See the Anthropic models page for up-to-date availability.

OpenAI:

curl https://api.openai.com/v1/models \
  -H "Authorization: Bearer $OPENAI_API_KEY" | jq '.data[].id'

See the OpenAI models page for up-to-date availability.

How It Works

[git commit] → [prepare-commit-msg hook]
   ↓
[commai generate]
   ├─ Read options from .commai/.config (model, interactive, autoCommit)
   ├─ Read staged diff via `git diff --cached`
   ├─ Check: existing user content? (skip if yes)
   ├─ Check: changes to stage? (skip if no)
   ├─ Create AI service (resolve model, load API key)
   ├─ Generate message via AI provider API (Claude or OpenAI)
   ├─ Interactive prompt (accept/regenerate/cancel)
   └─ Write to commit file or run `git commit -m`
   ↓
[commit proceeds or is cancelled]

Hook Chain Compatibility

commai respects other git tooling by chaining hooks:

.commai/prepare-commit-msg
  ├─ Run `commai generate`
  ├─ Then check `.husky/prepare-commit-msg` (run if executable)
  └─ Then check `.git/hooks/prepare-commit-msg` (run if executable)

This allows commai to coexist with husky, commitlint, and other pre-commit tooling.

What's Safe to Delete

  • Don't manually delete .commai/ — Run commai uninstall instead (it restores your git hook chain correctly)
  • Don't manually edit .commai/ — Hook scripts and .commai/.config are auto-generated. To change options, re-run commai install --model <model>
  • Safe to delete: .git/hooks/prepare-commit-msg (if not created by you), or third-party hooks if you're sure they're no longer needed

Troubleshooting

"ANTHROPIC_API_KEY environment variable is not set" / "OPENAI_API_KEY environment variable is not set"

The hook can't find the API key for the configured model's provider.

Fixes:

  1. Check which provider your model uses — see the Provider Auto-Detection table
  2. Check .env in your project root contains the right key (ANTHROPIC_API_KEY or OPENAI_API_KEY)
  3. Check ~/.commai/.env exists if using a global key
  4. Verify shell environment: echo $ANTHROPIC_API_KEY or echo $OPENAI_API_KEY
  5. If the .env is in a shared repo, make sure it's in .gitignore to avoid committing secrets

"Could not resolve model alias"

The model <family>@<version> didn't match any models in the provider's API.

Fixes:

  1. Verify the family name — Claude: sonnet, haiku, opus; OpenAI: gpt, o (case-insensitive)
  2. Check for typos in the version: latest is the safest default
  3. Check that the API key for the correct provider is set and valid
  4. Check that your API key has access to the model (some models are behind waitlists or org restrictions)
  5. Use the raw model ID as a fallback (e.g., claude-3-5-sonnet-20241022 or gpt-4-turbo), which skips the API lookup

Hook isn't running / commit skips message generation

Check if commai is installed:

git config core.hooksPath
# Should output: .commai

If empty or different, run commai install again.

Also note: commai intentionally exits early (without generating a message) in these cases:

  • No staged changes (git add nothing)
  • User already typed a message (commai respects manual input)
  • Merge/amend/squash commits (special git contexts where auto-generation is risky)

"EISDIR: illegal operation on a directory"

Likely trying to run commai outside a git repository.

# Fix: cd into a git repo
cd /path/to/project
commai install

Permission denied / hook file not executable

After installing, the hook script should be executable.

# Check
ls -l .commai/prepare-commit-msg
# Should show: -rwxr-xr-x (or similar, with x bits set)

# Fix if needed
chmod +x .commai/prepare-commit-msg

"AI call failed" / Network timeout

Network issues or API errors. commai logs the error and exits 0 (non-fatal, never blocks your commit) — your commit will still proceed without a generated message.

Debug (Claude):

curl https://api.anthropic.com/v1/messages \
  -H "api-key: $ANTHROPIC_API_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -H "content-type: application/json" \
  -d '{"model":"claude-3-5-haiku-20241022","max_tokens":100,"messages":[{"role":"user","content":"hi"}]}'

Debug (OpenAI):

curl https://api.openai.com/v1/chat/completions \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"gpt-4o-mini","max_tokens":100,"messages":[{"role":"user","content":"hi"}]}'

If either call fails, the issue is your API key or network connectivity.

License

MIT. See LICENSE for full text.


Questions? Check the Troubleshooting section or open an issue on GitHub.