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

gem-commit

v0.3.0

Published

Conventional Commits message recommender CLI powered by the Gemini CLI

Readme

gcommit

npm version npm downloads license node

A Conventional Commits message recommender CLI powered by the Gemini CLI. It feeds your staged diff to Gemini (gemini-2.5-flash), shows a few candidate messages, and commits with the one you pick.

Install: npm i -g gem-commit (the npm package is gem-commit; the installed command is gcommit).

The message language (English/Korean) and the number of candidates can be changed via gcommit config. Multi-provider support, model switching, and a "regenerate" flow are intentionally out of scope.


Requirements

  1. Node.js >= 18
  2. Gemini CLI must be installed on your PATH and authenticated.
  3. macOS / Linux / Windows (Windows 10+, Windows Terminal or recent conhost recommended)

gcommit only spawns the Gemini CLI as a child process — it never handles API keys directly.


Usage

git add <files>
gcommit
  1. The staged diff is read and sent to Gemini (with a progress indicator that shows elapsed time).
  2. Conventional Commits candidates (3 English messages by default; configurable via gcommit config) are shown as an interactive list.
  3. Selection controls:
    • / (or k/j) — move
    • Enter — confirm the highlighted candidate
    • 19 — pick that candidate by number and confirm immediately (up to the candidate count)
    • q / ESC / Ctrl+C — cancel
  4. git commit runs immediately with the chosen message.

In non-TTY environments (pipes, CI, etc.) interactive selection is unavailable; candidates are printed and the run is cancelled.

If Gemini exits with an error or returns output that can't be parsed, its stderr is printed to help diagnose the failure. Cancelling with Ctrl+C also stops the underlying gemini process so it doesn't keep running in the background.

Reword an existing commit

Regenerate the message for a commit that already exists, then replace it:

gcommit reword <commit>     # e.g. HEAD, HEAD~2, a1b2c3d

The commit's diff is sent to Gemini the same way, you pick from the candidates, and the message is rewritten:

  • HEAD → rewritten with git commit --amend.
  • An older commit → rewritten via a non-interactive rebase that touches only that commit's message.

Only commits on a linear, merge-free path from the target up to HEAD are supported. Before rewriting, gcommit checks that:

  • the target is an ancestor of HEAD (not on a different branch),
  • neither the target nor anything between it and HEAD is a merge commit,
  • the working tree is clean.

If any check fails it stops with a clear message. Rewriting a commit that was already pushed is allowed but warned about — you'll need a force-push afterward.

Exit codes

| Code | Meaning | | --- | --- | | 0 | Success / user cancelled | | 1 | Generic error (not a git repo, parse failure, git commit failure, …) | | 2 | Gemini CLI missing or auth error | | 3 | No staged changes |

Flags

  • gcommit --help, -h — show help
  • gcommit --version, -v — show version
  • gcommit reword --help — help for the reword subcommand

CLI flags don't change behavior. Persistent settings (language, candidate count) live under gcommit config.


Configuration (gcommit config)

gcommit config                 # interactive wizard (language → candidate count)
gcommit config get             # print all current values
gcommit config get <key>       # print a single key's value
gcommit config set <key> <val> # update and persist
gcommit config path            # print the current config file path

Supported keys:

| Key | Allowed values | Default | | --- | --- | --- | | lang | en / ko | en | | candidates | integer 19 | 3 |

Storage location

The file location is picked automatically based on how gcommit itself is installed.

| Install form | Storage location | | --- | --- | | Global install (npm i -g gem-commit) or npm link — macOS/Linux | $XDG_CONFIG_HOME/gcommit/config.json (defaults to ~/.config/gcommit/config.json) | | Global install — Windows | %APPDATA%\gcommit\config.json (defaults to C:\Users\<user>\AppData\Roaming\gcommit\config.json) | | Project devDependency (npm i -D gem-commit) | <project-root>/.gcommitrc.json |

Whether to commit a project-level .gcommitrc.json is up to each project's policy (committing it is usually fine).


Fixed parameters

| Item | Value | | --- | --- | | Model | gemini-2.5-flash | | Max diff size | 50,000 bytes (anything beyond is truncated with a warning) | | Commit format | Conventional Commits | | type keywords | feat, fix, docs, style, refactor, perf, test, build, ci, chore, revert |

The model, diff limit, and allowed type list are hard-coded in src/constants.js.


Flow

git add → gcommit
  │
  ├─ verify we're in a git repo
  ├─ verify `gemini --version` works
  ├─ git diff --cached (truncate if > 50KB)
  ├─ load config (lang / candidates saved via `gcommit config`)
  ├─ gemini -p <prompt> --output-format json -m gemini-2.5-flash (stdin: diff)
  ├─ parse → N candidates (retry once on failure)
  ├─ interactive selection (↑/↓ · Enter · 1-N · q/ESC)
  └─ git commit -F <tempfile> → delete tempfile → print result

Development

npm install
node bin/cli.js   # run locally

Project layout

gcommit/
├─ package.json
├─ README.md
├─ bin/
│  └─ cli.js          # #!/usr/bin/env node — dispatches run() / config / reword
└─ src/
   ├─ index.js        # staged-commit flow (config → diff → choose → commit)
   ├─ reword.js       # `gcommit reword <sha>` flow (validate → choose → amend/rebase)
   ├─ candidates.js   # shared generate + interactive choose (used by both flows)
   ├─ constants.js    # fixed values + default config / validation ranges
   ├─ config.js       # install-scope detection, path resolution, load/save/validate
   ├─ configCli.js    # `gcommit config` subcommand (wizard + get/set/path)
   ├─ git.js          # isRepo, diff/commit, plus reword helpers (amend, rebase, checks)
   ├─ gemini.js       # ensureInstalled, runGemini, parseResponse, generateCandidates
   ├─ prompt.js       # buildPrompt(config) — English/Korean + N candidates
   └─ ui.js           # output + readline-based pickers (chooseCandidate, chooseOne)

Out of scope

Multi-provider support (Claude/Codex), model switching, git-hook integration, and a "regenerate" flow are all out of scope. (Message language and candidate count are still configurable via gcommit config.)


License

MIT