@kyubiware/commit-mint 0.5.6 → 0.6.1

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
+ [![GitHub stars](https://img.shields.io/github/stars/kyubiware/commit-mint?style=flat&logo=github)](https://github.com/kyubiware/commit-mint)
6
+
7
+ - Runs your pre-commit checks on changed files, then digests failures into a
8
+ structured error report you can copy to clipboard — paste straight into a
9
+ coding agent.
10
+ - Looks at what you changed and uses AI to group files into logical commits.
11
+ - Generates a good commit message for each group.
49
12
 
50
13
  ## Install
51
14
 
@@ -53,148 +16,349 @@ 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
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).
27
+
28
+ ## Usage
63
29
 
64
30
  ```bash
65
- cmint config # set provider + API key (interactive wizard)
66
- cmint -a # auto-group, generate messages, commit everything
31
+ cmint # interactive: stage checks review → commit
32
+ cmint -a # auto-group, generate messages, commit everything
33
+ cmint config # edit provider, model, locale, etc.
67
34
  ```
68
35
 
69
- On first run you'll be prompted for an API key if one isn't configured. It's saved for future runs.
36
+ See [all flags](#all-flags) for the full list.
70
37
 
71
- ## Usage
38
+ ## Pre-flight checks (`.cmintrc`)
39
+
40
+ `.cmintrc` is commit-mint's pre-commit check system. The config syntax is
41
+ identical to [lint-staged](https://github.com/okonet/lint-staged) — glob keys
42
+ mapping to shell commands — but the checks run inside commit-mint's flow, not
43
+ as a separate git hook.
44
+
45
+ **Already using lint-staged?** Rename your config file to `.cmintrc` — same
46
+ syntax, no changes needed.
47
+
48
+ Run `cmint config` to auto-generate one, or create it manually:
49
+
50
+ ```ts
51
+ // .cmintrc.ts
52
+ export default {
53
+ "*.{js,ts,json}": "biome check --write --no-errors-on-unmatched --error-on-warnings",
54
+ "*.ts": () => ["tsc --noEmit", "vitest run --passWithNoTests", "npm run build"],
55
+ };
56
+ ```
57
+
58
+ (This is the actual `.cmintrc.ts` commit-mint ships with for its own
59
+ development.)
60
+
61
+ Checks run inside commit-mint's flow for three reasons:
62
+
63
+ **1. Checks run before the AI call.** A failing check short-circuits before
64
+ any API call. With lint-staged, the hook fires after the message is already
65
+ finalized — a broken check wastes the message.
66
+
67
+ **2. Failures get a recovery menu, not raw stderr.** commit-mint parses biome,
68
+ tsc, vitest/jest, eslint, and lint-staged output into structured errors, then
69
+ lets you copy the error report to clipboard — paste straight into a coding
70
+ agent.
71
+
72
+ **3. Live retry.** Fix the error in another terminal, pick "Retry checks" in
73
+ the menu — no need to exit and re-run `cmint`.
74
+
75
+ Config shape details, file name patterns, and the failure menu are documented
76
+ [below](#config-reference).
77
+
78
+ ## Auto-group mode (`-a`)
79
+
80
+ When you have 10 changed files across 3 concerns, `cmint -a` makes 3 commits,
81
+ each with its own message. The flow:
82
+
83
+ 1. Excluded files (lockfiles, build output) are committed upfront with a
84
+ hardcoded `chore: update lockfile` message.
85
+ 2. `.cmintrc` checks run on the remaining files.
86
+ 3. The AI groups files by intent.
87
+ 4. Each group is staged, diffed, and committed sequentially. A per-group
88
+ message is generated, and (in non-`auto` mode) reviewed.
89
+ 5. A hook failure on any group shows the recovery menu and stops the sequence
90
+ — the remaining groups are not committed.
91
+
92
+ `cmint` (no `-a`) on multiple files shows a staging menu:
72
93
 
73
- ```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
82
94
  ```
95
+ What do you want to stage?
96
+ Stage all files
97
+ Select files...
98
+ Auto-group into commits
99
+ Run checks
100
+ ```
101
+
102
+ ## AI Agent Mode
83
103
 
84
- ## Comparison
104
+ `cmint --agent` runs non-interactively with JSON output for AI coding agents.
85
105
 
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** | ✅ | — | — | ✅ | — |
106
+ | Combination | Behavior |
107
+ |---|---|
108
+ | `--agent` | Auto-group, AI generates, no review, JSON output |
109
+ | `--agent --message "msg"` | Single-commit mode, use provided message, no AI |
110
+ | `--agent --retry` | ERROR: incompatible (exit 1) |
111
+ | `--agent --noCheck` | Skip user-defined checks |
112
+ | `--agent --hint "..."` | Pass hint to AI |
113
+ | `--agent --debug` | Verbose logging to stderr |
97
114
 
98
- ## Modes
115
+ ### JSON output schema
99
116
 
100
- ### Auto mode (`-a`)
117
+ The command returns a single JSON object to stdout.
101
118
 
102
- `cmint -a` runs the full pipeline with no prompts:
119
+ ```json
120
+ {"status":"success","commits":[{"message":"feat: add X","hash":"abc123","files":["src/a.ts"]}]}
121
+ {"status":"no_changes","commits":[]}
122
+ {"status":"failure","commits":[],"errors":["error detail"]}
123
+ {"status":"cancelled","commits":[]}
124
+ ```
103
125
 
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.
126
+ ### Exit codes
109
127
 
110
- ### Manual mode
128
+ | Code | Meaning |
129
+ |------|---------|
130
+ | 0 | Success |
131
+ | 1 | Generic error |
132
+ | 2 | No changes |
133
+ | 3 | Git error |
134
+ | 4 | AI error |
135
+ | 5 | Check failure |
136
+ | 6 | Hook failure |
111
137
 
112
- Run `cmint` without flags for the interactive flow:
138
+ ### AI Coding Agent Integration
113
139
 
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.
140
+ For OpenCode or other AI coding environments, you can install cmint as a skill:
118
141
 
119
- Single-file changes are staged automatically.
142
+ ```bash
143
+ npx skills add kyubiware/commit-mint
144
+ ```
120
145
 
121
146
  ## Recovery menu
122
147
 
123
- When a pre-commit hook blocks your commit, commit-mint parses the error and presents an interactive menu:
148
+ When a git hook blocks the commit, commit-mint parses the output and shows:
124
149
 
125
150
  ```
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
- ╰─────────────────────────────────────────────────╯
151
+ Pre-commit hook failed
152
+ [biome] src/cli.ts — unused variable
153
+ • [vitest] 1 test failed in test/cli.test.ts
154
+
155
+ What do you want to do?
156
+ Copy error report to clipboard
157
+ View full error output
158
+ Skip hooks and commit (--no-verify)
159
+ Re-stage files and retry
160
+ Edit commit message
161
+ Cancel
141
162
  ```
142
163
 
143
- Errors are parsed from **lint-staged**, **biome**, **tsc**, **vitest**/**jest**, and **eslint**. Unrecognized output falls back to raw stderr.
164
+ Six options, none are dead ends:
144
165
 
145
- ## Pre-flight checks
166
+ - **Copy error report** — raw stderr to clipboard, formatted for an AI agent.
167
+ - **View full error output** — show the unparsed stderr in a note.
168
+ - **Skip hooks** — commit with `--no-verify`. Use when the failure is
169
+ understood and not worth blocking on.
170
+ - **Re-stage** — `git add -A`, retry the commit. Picks up fixes you make in
171
+ another terminal without restarting cmint. If re-stage still fails, the
172
+ menu re-shows the errors.
173
+ - **Edit** — tweak the AI message, then retry.
174
+ - **Cancel** — exit. The message is cached; `cmint -r` re-attempts with the
175
+ same message after you fix the underlying issue.
146
176
 
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.
177
+ Hook progress is shown in real time during the commit — `[STARTED]` /
178
+ `[COMPLETED]` / `[FAILED]` markers from each task are streamed to stderr as
179
+ they happen.
148
180
 
149
- ```js
150
- // .cmintrc.ts
181
+ Errors are parsed from **lint-staged**, **biome**, **tsc**, **vitest**/**jest**,
182
+ and **eslint**. Unrecognized output falls back to a single raw-stderr entry.
183
+
184
+ ## Providers
185
+
186
+ | Provider | Env var | Default model |
187
+ | -------- | ----------------- | -------------------- |
188
+ | Groq | `GROQ_API_KEY` | `openai/gpt-oss-20b` |
189
+ | Cerebras | `CEREBRAS_API_KEY` | `gpt-oss-120b` |
190
+ | Mistral | `MISTRAL_API_KEY` | `mistral-small` |
191
+
192
+ All three use OpenAI-compatible APIs. Groq uses the official SDK; Cerebras and
193
+ Mistral use a built-in fetch client. Per-provider model overrides: set
194
+ `model_groq`, `model_cerebras`, or `model_mistral` in `~/.commit-mint`.
195
+ Resolution order is `model_<provider>` → `model` → provider default.
196
+
197
+ `cmint config` walks you through provider, API key, model, locale, and
198
+ timeout.
199
+
200
+ ## Configuration
201
+
202
+ `~/.commit-mint` (INI format). Run `cmint config` to edit.
203
+
204
+ | Key | Default | Description |
205
+ | ---------------- | -------------------- | ------------------------------------------------- |
206
+ | `provider` | `groq` | `groq`, `cerebras`, or `mistral` |
207
+ | `model` | `openai/gpt-oss-20b` | Default model; overridable per provider |
208
+ | `model_groq` | — | Override default when provider is `groq` |
209
+ | `model_cerebras` | — | Override default when provider is `cerebras` |
210
+ | `model_mistral` | — | Override default when provider is `mistral` |
211
+ | `locale` | `en` | Locale for generated messages |
212
+ | `max-length` | `100` | Max commit message length |
213
+ | `type` | — | Force commit type prefix |
214
+ | `timeout` | `10000` | AI request timeout in ms |
215
+ | `proxy` | — | Proxy URL for API requests |
216
+ | `--agent` | `false` | Headless JSON-output mode for AI agents |
217
+
218
+ API key lookup checks the env var first, then the INI file.
219
+
220
+ ## Excluded files
221
+
222
+ These patterns are filtered from AI generation by default:
223
+
224
+ ```
225
+ package-lock.json
226
+ node_modules/** dist/** build/** .next/** coverage/**
227
+ *.log *.min.js *.min.css *.lock .DS_Store
228
+ ```
229
+
230
+ When every staged file matches an exclude, commit-mint uses a hardcoded
231
+ message: `chore: update lockfile` for lockfiles, `chore: update generated
232
+ files` for the rest. In auto-group mode, lockfiles (`package-lock.json`,
233
+ `pnpm-lock.yaml`, `yarn.lock`, `bun.lock`, `bun.lockb`) are promoted
234
+ alongside their companion manifest (e.g. `package-lock.json` stays with
235
+ `package.json`).
236
+
237
+ ## All flags
238
+
239
+ | Flag | Description |
240
+ | ----------------------- | ------------------------------------------------ |
241
+ | `-m`, `--message` | Use your own message instead of AI generation |
242
+ | `-H`, `--hint` | Context hint to the AI (e.g. "refactor only") |
243
+ | `-r`, `--retry` | Retry last failed commit (cached message) |
244
+ | `-N`, `--noCheck` | Skip pre-flight checks |
245
+ | `-d`, `--debug` | Debug logging to stderr |
246
+ | `--agent` | Headless JSON mode for AI coding agents |
247
+
248
+ ## Config reference
249
+
250
+ ### Config file names
251
+
252
+ Checked in this order. First match wins.
253
+
254
+ ```
255
+ .cmintrc
256
+ .cmintrc.json
257
+ .cmintrc.mjs
258
+ .cmintrc.mts
259
+ .cmintrc.js
260
+ .cmintrc.ts
261
+ .cmintrc.cjs
262
+ .cmintrc.cts
263
+ cmint.config.mjs
264
+ cmint.config.mts
265
+ cmint.config.js
266
+ cmint.config.ts
267
+ cmint.config.cjs
268
+ cmint.config.cts
269
+ ```
270
+
271
+ `.ts`/`.cts`/`.cjs` are loaded via [jiti](https://github.com/unjs/jiti) — use
272
+ TypeScript syntax freely. `.json` is parsed as plain JSON. Everything else is
273
+ loaded as ESM with `import default`.
274
+
275
+ ### Config shape
276
+
277
+ A default export. Each key is a [picomatch](https://github.com/micromatch/picomatch)
278
+ glob; each value is a command string, a string array, or a function that
279
+ returns either.
280
+
281
+ **String commands** get matched files appended as trailing arguments. Files
282
+ with spaces in their paths are quoted automatically.
283
+
284
+ ```ts
151
285
  export default {
152
- "*.{js,ts,json}": "biome check --write --no-errors-on-unmatched",
153
- "*.ts": () => ["tsc --noEmit", "vitest run --passWithNoTests"],
286
+ "*.ts": "eslint --fix", // runs `eslint --fix src/foo.ts src/bar.ts`
154
287
  };
155
288
  ```
156
289
 
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).
290
+ **String arrays** run sequentially, each as a separate command. First failure
291
+ stops the run.
158
292
 
159
- Supported config file names: `.cmintrc`, `.cmintrc.json`, `.cmintrc.{mjs,mts,js,ts,cjs,cts}`, `cmint.config.{mjs,mts,js,ts,cjs,cts}`
293
+ ```ts
294
+ export default {
295
+ "*.ts": ["eslint --fix", "prettier --write"],
296
+ };
297
+ ```
160
298
 
161
- ## Providers
299
+ **Function commands** receive the matched files and return a command or array
300
+ of commands. Use these when the command depends on the file list, or you want
301
+ multiple commands from one glob:
302
+
303
+ ```ts
304
+ export default {
305
+ "*.ts": (files) =>
306
+ files.length > 5 ? `vitest run ${files.join(" ")}` : "vitest run",
307
+ };
308
+ ```
162
309
 
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` |
310
+ ### Glob matching
168
311
 
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).
312
+ - Globs without a `/` match at any depth (e.g. `*.ts` matches `src/foo.ts` and
313
+ `a/b/c.ts`).
314
+ - Dotfiles are included.
315
+ - Paths with spaces are quoted before being appended.
170
316
 
171
- ## Configuration
317
+ ### Behavior
172
318
 
173
- Stored in `~/.commit-mint` (INI format). Run the wizard:
319
+ - Checks run after `git add`, before the AI call.
320
+ - Globs are processed in declaration order.
321
+ - Commands run sequentially per glob. First failure stops the run (fail-fast)
322
+ and skips remaining globs.
323
+ - 60s timeout per command. ENOENT (command not found) and timeouts are
324
+ reported back to the menu as their own error.
325
+ - Skipped entirely with `cmint -N`.
174
326
 
175
- ```bash
176
- cmint config
177
- ```
327
+ ### Failure menu
178
328
 
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 |
329
+ When a check fails, the same `parseHookErrors` pipeline that handles git
330
+ hooks runs, and a menu appears:
188
331
 
189
- ## Excluded files
332
+ ```
333
+ Pre-commit check failed
334
+ • [biome] src/services/ai.ts:12:1 lint/suspicious/noExplicitAny — Unexpected any...
335
+ • [tsc] src/services/ai.ts:55:18 — error TS2345: Argument of type 'string' is...
336
+
337
+ What do you want to do?
338
+ Copy error report to clipboard
339
+ View full error output
340
+ Retry checks
341
+ Skip checks and commit
342
+ Cancel
343
+ ```
344
+
345
+ - **Copy error report** — copies the raw stderr (works with `wl-copy`,
346
+ `xclip`, `xsel`, or `pbcopy`).
347
+ - **View full error output** — shows the raw stderr.
348
+ - **Retry checks** — re-runs the same checks. Fix in another terminal, hit
349
+ enter, no restart.
350
+ - **Skip checks and commit** — proceed to commit despite the failure.
351
+ - **Cancel** — exit. The message is cached so `cmint -r` re-attempts with the
352
+ same message.
190
353
 
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`).
354
+ For tsc failures specifically, the summary includes up to 3 file:line:column
355
+ diagnostics inline, with a `+N more` line if there are more.
192
356
 
193
357
  ## Requirements
194
358
 
195
- - **Node.js 18+**
196
- - **Git**
197
- - Optional clipboard tool for error copy: `wl-copy`, `xclip`, `xsel`, or `pbcopy`
359
+ - Node.js 18+
360
+ - git
361
+ - Optional, for clipboard copy: `wl-copy`, `xclip`, `xsel`, or `pbcopy`
198
362
 
199
363
  ## License
200
364