@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 +248 -141
- package/dist/cli.mjs +254 -11
- package/dist/cli.mjs.map +1 -1
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -1,51 +1,14 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
[: 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
|
+
[](https://www.npmjs.com/package/@kyubiware/commit-mint)
|
|
4
|
+
[](https://github.com/kyubiware/commit-mint/actions)
|
|
5
|
+
[](https://nodejs.org)
|
|
6
|
+
[](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
|
|
19
|
+
Or run without installing:
|
|
57
20
|
|
|
58
21
|
```bash
|
|
59
22
|
npx @kyubiware/commit-mint
|
|
60
23
|
```
|
|
61
24
|
|
|
62
|
-
|
|
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
|
|
75
|
-
cmint
|
|
76
|
-
cmint -m "feat: ..."
|
|
77
|
-
cmint -H "context"
|
|
78
|
-
cmint -r
|
|
79
|
-
cmint -N
|
|
80
|
-
cmint -d
|
|
81
|
-
cmint config
|
|
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
|
-
##
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
105
|
-
|
|
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
|
-
###
|
|
67
|
+
### Config file names
|
|
111
68
|
|
|
112
|
-
|
|
69
|
+
Checked in this order. First match wins.
|
|
113
70
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
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
|
-
|
|
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
|
-
|
|
92
|
+
### Config shape
|
|
122
93
|
|
|
123
|
-
|
|
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
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
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
|
-
|
|
119
|
+
**String arrays** run sequentially, each as a separate command. First failure
|
|
120
|
+
stops the run.
|
|
144
121
|
|
|
145
|
-
|
|
122
|
+
```ts
|
|
123
|
+
export default {
|
|
124
|
+
"*.ts": ["eslint --fix", "prettier --write"],
|
|
125
|
+
};
|
|
126
|
+
```
|
|
146
127
|
|
|
147
|
-
|
|
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
|
-
```
|
|
150
|
-
// .cmintrc.ts
|
|
132
|
+
```ts
|
|
151
133
|
export default {
|
|
152
|
-
|
|
153
|
-
|
|
134
|
+
"*.ts": (files) =>
|
|
135
|
+
files.length > 5 ? `vitest run ${files.join(" ")}` : "vitest run",
|
|
154
136
|
};
|
|
155
137
|
```
|
|
156
138
|
|
|
157
|
-
Glob
|
|
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
|
-
|
|
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
|
|
164
|
-
|
|
165
|
-
|
|
|
166
|
-
|
|
|
167
|
-
|
|
|
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
|
-
|
|
261
|
+
`cmint config` walks you through provider, API key, model, locale, and
|
|
262
|
+
timeout.
|
|
170
263
|
|
|
171
264
|
## Configuration
|
|
172
265
|
|
|
173
|
-
|
|
266
|
+
`~/.commit-mint` (INI format). Run `cmint config` to edit.
|
|
174
267
|
|
|
175
|
-
|
|
176
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
-
|
|
196
|
-
-
|
|
197
|
-
- Optional
|
|
302
|
+
- Node.js 18+
|
|
303
|
+
- git
|
|
304
|
+
- Optional, for clipboard copy: `wl-copy`, `xclip`, `xsel`, or `pbcopy`
|
|
198
305
|
|
|
199
306
|
## License
|
|
200
307
|
|