@kyubiware/commit-mint 0.5.6 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,51 +1,14 @@
1
- # 🌿 commit-mint
2
-
3
- [![npm version](https://img.shields.io/npm/v/@kyubiware/commit-mint.svg)](https://www.npmjs.com/package/@kyubiware/commit-mint)
4
- [![Build Status](https://img.shields.io/github/actions/workflow/status/kyubiware/commit-mint/ci.yml?style=flat-square)](https://github.com/kyubiware/commit-mint/actions)
5
- ![Node.js](https://img.shields.io/badge/Node.js->=18-3c873a?style=flat-square)
6
- [![License](https://img.shields.io/badge/License-MIT-blue?style=flat-square)](LICENSE)
7
-
8
- **AI commit messages that actually handle what goes wrong.**
9
-
10
- commit-mint generates conventional commit messages from your diff — and when hooks fail, it parses the errors and gives you a recovery menu instead of dumping raw stderr. It auto-groups unrelated changes into separate commits, runs your checks before generating messages, and caches failed attempts for instant retries.
11
-
12
- ```
13
- ┌ commit-mint
14
-
15
- ◇ Files analyzed
16
-
17
- ● Commit group 1 of 3: "Reading view refactor"
18
-
19
- ◇ Message generated
20
-
21
- ● feat(compound): add compound utilities and token handling for text study
22
-
23
- ◇ Committed successfully.
24
-
25
- ● ✓ biome
26
- │ ✓ eslint
27
- │ ✓ tsc
28
- │ ✓ vitest
29
-
30
- ● Commit group 2 of 3: "Panel refactor"
31
- ◇ Message generated
32
-
33
- ● feat(text-study): add compound component support to ReadingInspectorPanel
34
-
35
- ◇ Committed successfully.
36
-
37
- └ All groups committed.
38
- ```
39
-
40
- ## Why commit-mint
41
-
42
- Most AI commit tools generate a message and hope for the best. commit-mint handles the full loop:
43
-
44
- - **Auto-groups files by intent** — 10 changed files across 3 concerns? Three separate commits, each with its own message. No competitor does this.
45
- - **Hook failures get a recovery menu** — Parsed errors from biome, tsc, vitest, eslint, and lint-staged. Copy, skip, restage, edit, or cancel. No raw stderr dumps.
46
- - **Pre-flight checks before AI generation** — `.cmintrc` runs your checks after staging but before the API call, so a failing check never wastes tokens.
47
- - **Works without OpenAI** — Groq, Cerebras, and Mistral out of the box. No OpenAI key required.
48
- - **Cached retries** — Failed commit? Fix the error and `cmint --retry` picks up the same message.
1
+ # commit-mint
2
+
3
+ [![npm](https://img.shields.io/npm/v/@kyubiware/commit-mint.svg)](https://www.npmjs.com/package/@kyubiware/commit-mint)
4
+ [![CI](https://img.shields.io/github/actions/workflow/status/kyubiware/commit-mint/ci.yml)](https://github.com/kyubiware/commit-mint/actions)
5
+ [![Node](https://img.shields.io/badge/node-%3E%3D18-3c873a)](https://nodejs.org)
6
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue)](LICENSE)
7
+
8
+ A commit tool that handles hook failures. Generates conventional commit messages
9
+ from your diff, auto-groups unrelated changes into separate commits, runs your
10
+ checks before any API call, and gives you a recovery menu when hooks block the
11
+ commit instead of dumping raw stderr.
49
12
 
50
13
  ## Install
51
14
 
@@ -53,148 +16,292 @@ Most AI commit tools generate a message and hope for the best. commit-mint handl
53
16
  npm install -g @kyubiware/commit-mint
54
17
  ```
55
18
 
56
- Or try it without installing:
19
+ Or run without installing:
57
20
 
58
21
  ```bash
59
22
  npx @kyubiware/commit-mint
60
23
  ```
61
24
 
62
- ## Quick start
63
-
64
- ```bash
65
- cmint config # set provider + API key (interactive wizard)
66
- cmint -a # auto-group, generate messages, commit everything
67
- ```
68
-
69
- On first run you'll be prompted for an API key if one isn't configured. It's saved for future runs.
25
+ Requires Node.js 18+ and git. Run `cmint config` once to set the AI provider and
26
+ API key. The key is saved to `~/.commit-mint` (INI).
70
27
 
71
28
  ## Usage
72
29
 
73
30
  ```bash
74
- cmint -a # auto-group and commit everything
75
- cmint # interactive flow (staging checks → review → commit)
76
- cmint -m "feat: ..." # skip AI, use your own message
77
- cmint -H "context" # pass a hint for better AI messages
78
- cmint -r # retry last failed commit (cached message)
79
- cmint -N # skip pre-flight checks
80
- cmint -d # debug mode (timestamped stderr)
81
- cmint config # interactive configuration wizard
31
+ cmint # interactive: stage → checks → review → commit
32
+ cmint -a # auto-group, generate messages, commit everything
33
+ cmint -m "feat: ..." # skip AI, use your own message
34
+ cmint -H "context" # hint to the AI (e.g. "refactor only, no behavior change")
35
+ cmint -r # retry the last failed commit (cached message)
36
+ cmint -N # skip pre-flight checks
37
+ cmint -d # debug logging to stderr
38
+ cmint config # edit provider, model, locale, etc.
82
39
  ```
83
40
 
84
- ## Comparison
41
+ ## Pre-flight checks (`.cmintrc`)
42
+
43
+ `.cmintrc` is commit-mint's pre-commit check system. The config syntax is
44
+ identical to [lint-staged](https://github.com/okonet/lint-staged) — glob keys
45
+ mapping to shell commands — but the checks run inside commit-mint's flow, not
46
+ as a separate git hook.
85
47
 
86
- | | commit-mint | aicommits | opencommit | cz-git | commitizen |
87
- |---|:---:|:---:|:---:|:---:|:---:|
88
- | **Auto-group files into commits** | ✅ | — | — | — | — |
89
- | **Hook failure recovery menu** | ✅ | — | — | — | — |
90
- | **Pre-commit checks in-flow** | ✅ | — | — | — | — |
91
- | **AI message generation** | ✅ | ✅ | ✅ | ✅ | — |
92
- | **No OpenAI required** | ✅ Groq, Cerebras, Mistral | ✅ Together, Ollama | — default OpenAI | — OpenAI only | n/a |
93
- | **Message review before commit** | ✅ | ✅ | ✅ | ✅ interactive | ✅ interactive |
94
- | **Zero-prompt auto mode** | ✅ | ✅ | ✅ | — | — |
95
- | **Conventional commits** | ✅ | ✅ | ✅ | ✅ | ✅ |
96
- | **Retry cached message** | ✅ | — | — | ✅ | — |
48
+ This matters for three reasons:
97
49
 
98
- ## Modes
50
+ **1. Checks run before the AI call.** commit-mint runs checks before
51
+ generating the commit message. A failing check short-circuits before any API
52
+ call. With lint-staged, the hook fires after the message is already finalized
53
+ (if the AI call was made) or the user has typed one in — so a broken check
54
+ wastes the message.
99
55
 
100
- ### Auto mode (`-a`)
56
+ **2. Failures get a recovery menu, not raw stderr.** lint-staged prints whatever
57
+ the tool emitted and exits. commit-mint parses biome, tsc, vitest/jest, eslint,
58
+ and lint-staged output into structured errors. Then commit-mint lets you copy the error report to clipboard,
59
+ so you can paste straight to your coding agent.
101
60
 
102
- `cmint -a` runs the full pipeline with no prompts:
61
+ **3. Live retry.** After your coding agent fixes the error in another terminal, pick "Retry checks" in
62
+ the menu, no need to exit and re-run `cmint`.
103
63
 
104
- 1. Excluded files (lockfiles, generated) are committed upfront.
105
- 2. `.cmintrc` checks run before AI grouping.
106
- 3. AI groups files into logical commits by intent.
107
- 4. Each group gets a generated conventional commit message.
108
- 5. Groups are committed sequentially. Hook failures pause the sequence with a recovery menu.
64
+ Same syntax, fewer moving parts, and the checks live in the same process as
65
+ the rest of the commit.
109
66
 
110
- ### Manual mode
67
+ ### Config file names
111
68
 
112
- Run `cmint` without flags for the interactive flow:
69
+ Checked in this order. First match wins.
113
70
 
114
- 1. **Staging menu** — stage all, select files, auto-group, or run checks.
115
- 2. **Pre-flight checks** — `.cmintrc` checks run automatically (skip with `-N`).
116
- 3. **Message review** — review the AI message before committing.
117
- 4. **Commit** — hooks run, recovery menu on failure.
71
+ ```
72
+ .cmintrc
73
+ .cmintrc.json
74
+ .cmintrc.mjs
75
+ .cmintrc.mts
76
+ .cmintrc.js
77
+ .cmintrc.ts
78
+ .cmintrc.cjs
79
+ .cmintrc.cts
80
+ cmint.config.mjs
81
+ cmint.config.mts
82
+ cmint.config.js
83
+ cmint.config.ts
84
+ cmint.config.cjs
85
+ cmint.config.cts
86
+ ```
118
87
 
119
- Single-file changes are staged automatically.
88
+ `.ts`/`.cts`/`.cjs` are loaded via [jiti](https://github.com/unjs/jiti) — use
89
+ TypeScript syntax freely. `.json` is parsed as plain JSON. Everything else is
90
+ loaded as ESM with `import default`.
120
91
 
121
- ## Recovery menu
92
+ ### Config shape
122
93
 
123
- When a pre-commit hook blocks your commit, commit-mint parses the error and presents an interactive menu:
94
+ A default export. Each key is a [picomatch](https://github.com/micromatch/picomatch)
95
+ glob; each value is a command string, a string array, or a function that
96
+ returns either.
124
97
 
98
+ ```ts
99
+ // .cmintrc.ts
100
+ export default {
101
+ "*.{js,ts,json}": "biome check --write --no-errors-on-unmatched --error-on-warnings",
102
+ "*.ts": () => ["tsc --noEmit", "vitest run --passWithNoTests", "npm run build"],
103
+ };
125
104
  ```
126
- ╭─────────────────────────────────────────────────╮
127
- │ ✘ Pre-commit hook failed │
128
- │ │
129
- │ • biome: src/cli.ts — unused variable │
130
- │ • vitest: 1 test failed in test/cli.test.ts │
131
- │ │
132
- │ What do you want to do? │
133
- │ │
134
- │ Copy error report to clipboard │
135
- │ View full output │
136
- │ Skip hooks and commit (--no-verify) │
137
- │ Re-stage files and retry │
138
- │ Edit commit message │
139
- │ Cancel │
140
- ╰─────────────────────────────────────────────────╯
105
+
106
+ This is the actual `.cmintrc.ts` commit-mint ships with for its own
107
+ development — biome on staged JS/TS/JSON, then tsc + vitest + build on staged
108
+ TS.
109
+
110
+ **String commands** get matched files appended as trailing arguments. Files
111
+ with spaces in their paths are quoted automatically.
112
+
113
+ ```ts
114
+ export default {
115
+ "*.ts": "eslint --fix", // runs `eslint --fix src/foo.ts src/bar.ts`
116
+ };
141
117
  ```
142
118
 
143
- Errors are parsed from **lint-staged**, **biome**, **tsc**, **vitest**/**jest**, and **eslint**. Unrecognized output falls back to raw stderr.
119
+ **String arrays** run sequentially, each as a separate command. First failure
120
+ stops the run.
144
121
 
145
- ## Pre-flight checks
122
+ ```ts
123
+ export default {
124
+ "*.ts": ["eslint --fix", "prettier --write"],
125
+ };
126
+ ```
146
127
 
147
- `.cmintrc` is commit-mint's in-flow replacement for lint-staged. Define checks once at your project root and commit-mint runs them after staging but before AI generation — so failing checks never waste an API call.
128
+ **Function commands** receive the matched files and return a command or array
129
+ of commands. Use these when the command depends on the file list, or you want
130
+ multiple commands from one glob:
148
131
 
149
- ```js
150
- // .cmintrc.ts
132
+ ```ts
151
133
  export default {
152
- "*.{js,ts,json}": "biome check --write --no-errors-on-unmatched",
153
- "*.ts": () => ["tsc --noEmit", "vitest run --passWithNoTests"],
134
+ "*.ts": (files) =>
135
+ files.length > 5 ? `vitest run ${files.join(" ")}` : "vitest run",
154
136
  };
155
137
  ```
156
138
 
157
- Glob patterns use [picomatch](https://github.com/micromatch/picomatch). String commands receive matched files as trailing arguments. Functions receive the file list and return one or more commands. Checks run sequentially and fail fast (60s timeout per command).
139
+ ### Glob matching
140
+
141
+ - Globs without a `/` match at any depth (e.g. `*.ts` matches `src/foo.ts` and
142
+ `a/b/c.ts`).
143
+ - Dotfiles are included.
144
+ - Paths with spaces are quoted before being appended.
145
+
146
+ ### Behavior
147
+
148
+ - Checks run after `git add`, before the AI call.
149
+ - Globs are processed in declaration order.
150
+ - Commands run sequentially per glob. First failure stops the run (fail-fast)
151
+ and skips remaining globs.
152
+ - 60s timeout per command. ENOENT (command not found) and timeouts are
153
+ reported back to the menu as their own error.
154
+ - Skipped entirely with `cmint -N`.
158
155
 
159
- Supported config file names: `.cmintrc`, `.cmintrc.json`, `.cmintrc.{mjs,mts,js,ts,cjs,cts}`, `cmint.config.{mjs,mts,js,ts,cjs,cts}`
156
+ ### Failure menu
157
+
158
+ When a check fails, the same `parseHookErrors` pipeline that handles git
159
+ hooks runs, and a menu appears:
160
+
161
+ ```
162
+ Pre-commit check failed
163
+ • [biome] src/services/ai.ts:12:1 lint/suspicious/noExplicitAny — Unexpected any...
164
+ • [tsc] src/services/ai.ts:55:18 — error TS2345: Argument of type 'string' is...
165
+
166
+ What do you want to do?
167
+ Copy error report to clipboard
168
+ View full error output
169
+ Retry checks
170
+ Skip checks and commit
171
+ Cancel
172
+ ```
173
+
174
+ - **Copy error report** — copies the raw stderr (works with `wl-copy`,
175
+ `xclip`, `xsel`, or `pbcopy`).
176
+ - **View full error output** — shows the raw stderr.
177
+ - **Retry checks** — re-runs the same checks. Fix in another terminal, hit
178
+ enter, no restart.
179
+ - **Skip checks and commit** — proceed to commit despite the failure.
180
+ - **Cancel** — exit. The message is cached so `cmint -r` re-attempts with the
181
+ same message.
182
+
183
+ For tsc failures specifically, the summary includes up to 3 file:line:column
184
+ diagnostics inline, with a `+N more` line if there are more.
185
+
186
+ ## Auto-group mode (`-a`)
187
+
188
+ When you have 10 changed files across 3 concerns, `cmint -a` makes 3 commits,
189
+ each with its own message. The flow:
190
+
191
+ 1. Excluded files (lockfiles, build output) are committed upfront with a
192
+ hardcoded `chore: update lockfile` message.
193
+ 2. `.cmintrc` checks run on the remaining files.
194
+ 3. The AI groups files by intent.
195
+ 4. Each group is staged, diffed, and committed sequentially. A per-group
196
+ message is generated, and (in non-`auto` mode) reviewed.
197
+ 5. A hook failure on any group shows the recovery menu and stops the sequence
198
+ — the remaining groups are not committed.
199
+
200
+ `cmint` (no `-a`) on multiple files shows a staging menu:
201
+
202
+ ```
203
+ What do you want to stage?
204
+ Stage all files
205
+ Select files...
206
+ Auto-group into commits
207
+ Run checks
208
+ ```
209
+
210
+ ## Recovery menu
211
+
212
+ When a git hook blocks the commit, commit-mint parses the output and shows:
213
+
214
+ ```
215
+ Pre-commit hook failed
216
+ • [biome] src/cli.ts — unused variable
217
+ • [vitest] 1 test failed in test/cli.test.ts
218
+
219
+ What do you want to do?
220
+ Copy error report to clipboard
221
+ View full error output
222
+ Skip hooks and commit (--no-verify)
223
+ Re-stage files and retry
224
+ Edit commit message
225
+ Cancel
226
+ ```
227
+
228
+ Six options, none are dead ends:
229
+
230
+ - **Copy error report** — raw stderr to clipboard, formatted for an AI agent.
231
+ - **View full error output** — show the unparsed stderr in a note.
232
+ - **Skip hooks** — commit with `--no-verify`. Use when the failure is
233
+ understood and not worth blocking on.
234
+ - **Re-stage** — `git add -A`, retry the commit. Picks up fixes you make in
235
+ another terminal without restarting cmint. If re-stage still fails, the
236
+ menu re-shows the errors.
237
+ - **Edit** — tweak the AI message, then retry.
238
+ - **Cancel** — exit. The message is cached; `cmint -r` re-attempts with the
239
+ same message after you fix the underlying issue.
240
+
241
+ Hook progress is shown in real time during the commit — `[STARTED]` /
242
+ `[COMPLETED]` / `[FAILED]` markers from each task are streamed to stderr as
243
+ they happen.
244
+
245
+ Errors are parsed from **lint-staged**, **biome**, **tsc**, **vitest**/**jest**,
246
+ and **eslint**. Unrecognized output falls back to a single raw-stderr entry.
160
247
 
161
248
  ## Providers
162
249
 
163
- | Provider | Env key | Default model |
164
- |----------|---------|---------------|
165
- | **Groq** | `GROQ_API_KEY` | `openai/gpt-oss-20b` |
166
- | **Cerebras** | `CEREBRAS_API_KEY` | `gpt-oss-120b` |
167
- | **Mistral** | `MISTRAL_API_KEY` | `mistral-small` |
250
+ | Provider | Env var | Default model |
251
+ | -------- | ----------------- | -------------------- |
252
+ | Groq | `GROQ_API_KEY` | `openai/gpt-oss-20b` |
253
+ | Cerebras | `CEREBRAS_API_KEY` | `gpt-oss-120b` |
254
+ | Mistral | `MISTRAL_API_KEY` | `mistral-small` |
255
+
256
+ All three use OpenAI-compatible APIs. Groq uses the official SDK; Cerebras and
257
+ Mistral use a built-in fetch client. Per-provider model overrides: set
258
+ `model_groq`, `model_cerebras`, or `model_mistral` in `~/.commit-mint`.
259
+ Resolution order is `model_<provider>` → `model` → provider default.
168
260
 
169
- Use `cmint config` to switch providers or override the model per-provider. All providers use OpenAI-compatible APIs (Groq via official SDK, Cerebras and Mistral via built-in fetch client).
261
+ `cmint config` walks you through provider, API key, model, locale, and
262
+ timeout.
170
263
 
171
264
  ## Configuration
172
265
 
173
- Stored in `~/.commit-mint` (INI format). Run the wizard:
266
+ `~/.commit-mint` (INI format). Run `cmint config` to edit.
174
267
 
175
- ```bash
176
- cmint config
177
- ```
268
+ | Key | Default | Description |
269
+ | ---------------- | -------------------- | ------------------------------------------------- |
270
+ | `provider` | `groq` | `groq`, `cerebras`, or `mistral` |
271
+ | `model` | `openai/gpt-oss-20b` | Default model; overridable per provider |
272
+ | `model_groq` | — | Override default when provider is `groq` |
273
+ | `model_cerebras` | — | Override default when provider is `cerebras` |
274
+ | `model_mistral` | — | Override default when provider is `mistral` |
275
+ | `locale` | `en` | Locale for generated messages |
276
+ | `max-length` | `100` | Max commit message length |
277
+ | `type` | — | Force commit type prefix |
278
+ | `timeout` | `10000` | AI request timeout in ms |
279
+ | `proxy` | — | Proxy URL for API requests |
178
280
 
179
- | Key | Default | Description |
180
- |-----|---------|-------------|
181
- | `provider` | `groq` | AI provider (`groq`, `cerebras`, or `mistral`) |
182
- | `model` | `openai/gpt-oss-20b` | Default model (overridable per-provider with `model_groq`, `model_cerebras`, `model_mistral`) |
183
- | `locale` | `en` | Locale for generated messages |
184
- | `max-length` | `100` | Max commit message length |
185
- | `type` | — | Commit type prefix |
186
- | `timeout` | `10000` | AI request timeout in ms |
187
- | `proxy` | — | Proxy URL for API requests |
281
+ API key lookup checks the env var first, then the INI file.
188
282
 
189
283
  ## Excluded files
190
284
 
191
- Lockfiles, build output, and generated files are excluded from AI generation. When all staged files match excludes, commit-mint uses a hardcoded message (`chore: update lockfile` or `chore: update generated files`). In auto-group mode, lockfiles are promoted alongside their companion manifests (e.g. `package-lock.json` with `package.json`).
285
+ These patterns are filtered from AI generation by default:
286
+
287
+ ```
288
+ package-lock.json
289
+ node_modules/** dist/** build/** .next/** coverage/**
290
+ *.log *.min.js *.min.css *.lock .DS_Store
291
+ ```
292
+
293
+ When every staged file matches an exclude, commit-mint uses a hardcoded
294
+ message: `chore: update lockfile` for lockfiles, `chore: update generated
295
+ files` for the rest. In auto-group mode, lockfiles (`package-lock.json`,
296
+ `pnpm-lock.yaml`, `yarn.lock`, `bun.lock`, `bun.lockb`) are promoted
297
+ alongside their companion manifest (e.g. `package-lock.json` stays with
298
+ `package.json`).
192
299
 
193
300
  ## Requirements
194
301
 
195
- - **Node.js 18+**
196
- - **Git**
197
- - Optional clipboard tool for error copy: `wl-copy`, `xclip`, `xsel`, or `pbcopy`
302
+ - Node.js 18+
303
+ - git
304
+ - Optional, for clipboard copy: `wl-copy`, `xclip`, `xsel`, or `pbcopy`
198
305
 
199
306
  ## License
200
307