@mihairo/cmt 1.0.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/LICENSE +21 -0
- package/README.md +262 -0
- package/cmt +972 -0
- package/package.json +33 -0
- package/schema/cmt.schema.json +150 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Mihai Ro
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
# cmt
|
|
2
|
+
|
|
3
|
+
> Conventional Commits CLI โ zero dependencies, one bash script.
|
|
4
|
+
|
|
5
|
+
[](https://npmjs.com/package/cmt-cli)
|
|
6
|
+
[](https://conventionalcommits.org)
|
|
7
|
+
[](LICENSE)
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Install
|
|
12
|
+
|
|
13
|
+
**npm (any project โ no Node required at runtime)**
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install -g cmt-cli
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
**Homebrew**
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
brew tap mihairo/tap
|
|
23
|
+
brew install cmt
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
**curl (no package manager)**
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
curl -fsSL https://raw.githubusercontent.com/mihai-ro/cmt/main/cmt \
|
|
30
|
+
-o ~/.local/bin/cmt && chmod +x ~/.local/bin/cmt
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Usage
|
|
36
|
+
|
|
37
|
+
```
|
|
38
|
+
cmt <command> [flags]
|
|
39
|
+
|
|
40
|
+
init [--husky] [--lint] create .cmt.json + install git hook(s)
|
|
41
|
+
commit interactive commit builder
|
|
42
|
+
lint [file] lint a message file or stdin โ exit 1 on error
|
|
43
|
+
log [n] pretty log of last n commits (default: 20)
|
|
44
|
+
types list available commit types
|
|
45
|
+
uninstall remove cmt-managed hooks and .cmt.json
|
|
46
|
+
version
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
**Set up a repo:**
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
cd my-project
|
|
53
|
+
cmt init # picker hook only
|
|
54
|
+
cmt init --lint # picker + lint git commit -m "..." commits
|
|
55
|
+
cmt init --husky # husky v9 format (.husky/prepare-commit-msg)
|
|
56
|
+
cmt init --husky --lint # both hooks, husky format
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
**Guided interactive commit:**
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
git add .
|
|
63
|
+
git commit # triggers the interactive picker automatically
|
|
64
|
+
# or:
|
|
65
|
+
cmt commit # run directly
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
**Lint from anywhere:**
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
echo "feat(api): add login" | cmt lint # exit 0
|
|
72
|
+
echo "bad message" | cmt lint # exit 1
|
|
73
|
+
|
|
74
|
+
# lint every commit on a branch (CI)
|
|
75
|
+
git log --format="%s" origin/main..HEAD | while IFS= read -r msg; do
|
|
76
|
+
echo "$msg" | cmt lint || exit 1
|
|
77
|
+
done
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## Commit format
|
|
83
|
+
|
|
84
|
+
```
|
|
85
|
+
<type>[optional scope]: <description>
|
|
86
|
+
|
|
87
|
+
[optional body]
|
|
88
|
+
|
|
89
|
+
[optional footer(s)]
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
**Breaking change:**
|
|
93
|
+
|
|
94
|
+
```
|
|
95
|
+
feat!: drop support for Node 14
|
|
96
|
+
feat(api)!: redesign endpoints
|
|
97
|
+
BREAKING CHANGE: /auth now returns JWT
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
**Built-in types**
|
|
101
|
+
|
|
102
|
+
| Type | Emoji | SemVer impact |
|
|
103
|
+
| ---------- | ----- | ------------- |
|
|
104
|
+
| `feat` | โจ | minor |
|
|
105
|
+
| `fix` | ๐ | patch |
|
|
106
|
+
| `docs` | ๐ | โ |
|
|
107
|
+
| `style` | ๐
| โ |
|
|
108
|
+
| `refactor` | โป๏ธ | โ |
|
|
109
|
+
| `perf` | โก | patch |
|
|
110
|
+
| `test` | ๐งช | โ |
|
|
111
|
+
| `build` | ๐๏ธ | โ |
|
|
112
|
+
| `ci` | ๐ง | โ |
|
|
113
|
+
| `chore` | ๐ฉ | โ |
|
|
114
|
+
| `revert` | โช | patch |
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
## Configuration โ `.cmt.json`
|
|
119
|
+
|
|
120
|
+
`cmt init` creates `.cmt.json` at your repo root with a `$schema` pointer.
|
|
121
|
+
VS Code, JetBrains, and any JSON Language Server will autocomplete and
|
|
122
|
+
validate it automatically โ no extension needed.
|
|
123
|
+
|
|
124
|
+
```json
|
|
125
|
+
{
|
|
126
|
+
"$schema": "https://raw.githubusercontent.com/mihai-ro/cmt/main/schema/cmt.schema.json",
|
|
127
|
+
"version": "1.0.0",
|
|
128
|
+
"customTypes": [
|
|
129
|
+
{
|
|
130
|
+
"type": "wip",
|
|
131
|
+
"emoji": "๐ง",
|
|
132
|
+
"semver": "none",
|
|
133
|
+
"description": "Work in progress"
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
"type": "security",
|
|
137
|
+
"emoji": "๐",
|
|
138
|
+
"semver": "patch",
|
|
139
|
+
"description": "Security fix"
|
|
140
|
+
}
|
|
141
|
+
],
|
|
142
|
+
"scopes": ["auth", "api", "ui", "db"],
|
|
143
|
+
"rules": {
|
|
144
|
+
"maxHeaderLength": 72,
|
|
145
|
+
"requireScope": false,
|
|
146
|
+
"allowBreakingChanges": ["feat", "fix"],
|
|
147
|
+
"disallowUpperCaseDescription": false,
|
|
148
|
+
"disallowTrailingPeriod": false
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
**Scopes** โ when the `scopes` array is non-empty, `cmt commit` shows an
|
|
154
|
+
arrow-key picker with your configured scopes, a "custom" option for free-text
|
|
155
|
+
entry, and a "skip" option. Leave `scopes` empty to always use free-text input.
|
|
156
|
+
|
|
157
|
+
Commit `.cmt.json` โ your whole team shares the same types, scopes, and rules.
|
|
158
|
+
|
|
159
|
+
---
|
|
160
|
+
|
|
161
|
+
## Hooks
|
|
162
|
+
|
|
163
|
+
### `prepare-commit-msg` (always installed)
|
|
164
|
+
|
|
165
|
+
Intercepts plain `git commit`, runs the interactive picker, and writes the
|
|
166
|
+
message โ so git never opens its editor. Skips amends, merges, squashes, and
|
|
167
|
+
any commit that already has a source message.
|
|
168
|
+
|
|
169
|
+
### `commit-msg` (opt-in via `--lint`)
|
|
170
|
+
|
|
171
|
+
Lints the final commit message. Catches `git commit -m "..."`, `--amend`,
|
|
172
|
+
and commits from GUI tools:
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
cmt init --lint
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
Both hooks follow the same append/create pattern โ if a hook file already
|
|
179
|
+
exists they append a clearly-marked block rather than overwriting it.
|
|
180
|
+
`cmt uninstall` removes only the cmt blocks, leaving any other content intact.
|
|
181
|
+
|
|
182
|
+
---
|
|
183
|
+
|
|
184
|
+
## Integrations
|
|
185
|
+
|
|
186
|
+
### Husky v9
|
|
187
|
+
|
|
188
|
+
```bash
|
|
189
|
+
cmt init --husky --lint # writes .husky/prepare-commit-msg + .husky/commit-msg
|
|
190
|
+
git add .husky/ # commit them โ every teammate gets them on clone
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### lint-staged
|
|
194
|
+
|
|
195
|
+
Add to `.husky/pre-commit`:
|
|
196
|
+
|
|
197
|
+
```sh
|
|
198
|
+
npx lint-staged
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
`cmt` handles commit message linting separately โ the two hooks are completely independent.
|
|
202
|
+
|
|
203
|
+
### GitHub Actions
|
|
204
|
+
|
|
205
|
+
```yaml
|
|
206
|
+
- name: Lint commit messages
|
|
207
|
+
run: |
|
|
208
|
+
git log --format="%s" origin/main..HEAD | while IFS= read -r msg; do
|
|
209
|
+
echo "$msg" | cmt lint || exit 1
|
|
210
|
+
done
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### Git operations and hook behaviour
|
|
214
|
+
|
|
215
|
+
| Operation | Hook fires? | Result |
|
|
216
|
+
| --------------------- | ---------------- | ------------------------------------ |
|
|
217
|
+
| `git commit` | โ
| picker runs |
|
|
218
|
+
| `git commit -m "..."` | โ
with `--lint` | linted |
|
|
219
|
+
| `git commit --amend` | โ
with `--lint` | linted |
|
|
220
|
+
| `git merge --no-ff` | โ
| โญ skipped (auto-generated message) |
|
|
221
|
+
| `git revert` | โ
| โญ skipped (auto-generated message) |
|
|
222
|
+
| `fixup!` / `squash!` | โ
| โญ skipped |
|
|
223
|
+
| `git pull --rebase` | โ
| โ
passes (replays existing commits) |
|
|
224
|
+
| Empty/aborted commit | โ
| โญ skipped |
|
|
225
|
+
|
|
226
|
+
---
|
|
227
|
+
|
|
228
|
+
## Lint rules
|
|
229
|
+
|
|
230
|
+
| Rule | Config key | Default | On fail |
|
|
231
|
+
| ----------------------------------------- | ------------------------------ | -------- | ---------- |
|
|
232
|
+
| Header format `type(scope)?: description` | โ | required | โ error |
|
|
233
|
+
| Valid type | โ | required | โ error |
|
|
234
|
+
| Non-empty description | โ | required | โ error |
|
|
235
|
+
| Blank line before body | โ | required | โ error |
|
|
236
|
+
| Scope required | `requireScope` | `false` | โ error |
|
|
237
|
+
| Uppercase description | `disallowUpperCaseDescription` | `false` | โ ๏ธ / โ |
|
|
238
|
+
| Trailing period | `disallowTrailingPeriod` | `false` | โ ๏ธ / โ |
|
|
239
|
+
| Header length | `maxHeaderLength` | `72` | โ ๏ธ warning |
|
|
240
|
+
|
|
241
|
+
Warnings exit `0`. Errors exit `1`.
|
|
242
|
+
|
|
243
|
+
---
|
|
244
|
+
|
|
245
|
+
## Why not commitlint + husky + commitizen?
|
|
246
|
+
|
|
247
|
+
| | **cmt** | commitlint + husky | commitizen |
|
|
248
|
+
| -------------------------- | ------------------ | ------------------ | --------------- |
|
|
249
|
+
| Runtime dependencies | **0** | ~15 npm packages | Python + pip |
|
|
250
|
+
| Works in any language repo | โ
| โ needs Node | โ needs Python |
|
|
251
|
+
| Install | copy one file | `npm install` | `pip install` |
|
|
252
|
+
| Interactive commit prompt | โ
| via cz-commitlint | โ
|
|
|
253
|
+
| Commit-msg linting | โ
opt-in `--lint` | โ
| โ
|
|
|
254
|
+
| Husky v9 support | โ
| native | via config |
|
|
255
|
+
| JSON Schema / intellisense | โ
| partial | โ |
|
|
256
|
+
| Custom types + scopes | โ
`.cmt.json` | โ
| โ
|
|
|
257
|
+
|
|
258
|
+
---
|
|
259
|
+
|
|
260
|
+
## License
|
|
261
|
+
|
|
262
|
+
MIT
|