@verndale/ai-commit 2.4.2 → 2.4.4
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/.env-example +0 -29
- package/README.md +138 -52
- package/package.json +1 -1
package/.env-example
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
# Copy to .env and/or .env.local in your project root (do not commit secrets).
|
|
2
|
-
|
|
3
1
|
# ------------------------------------------------------------
|
|
4
2
|
# @verndale/ai-commit (pnpm commit / ai-commit run)
|
|
5
3
|
# ------------------------------------------------------------
|
|
@@ -9,30 +7,3 @@ OPENAI_API_KEY=
|
|
|
9
7
|
# Optional — default is gpt-4o-mini
|
|
10
8
|
# COMMIT_AI_MODEL=
|
|
11
9
|
|
|
12
|
-
|
|
13
|
-
# ------------------------------------------------------------
|
|
14
|
-
# @verndale/ai-pr (pnpm open-pr) — GitHub PR create/update
|
|
15
|
-
# ------------------------------------------------------------
|
|
16
|
-
# @verndale/ai-pr — GH_TOKEN: Set for local CLI runs; CI uses workflow env / secrets. Also reads GITHUB_TOKEN.
|
|
17
|
-
#GH_TOKEN=
|
|
18
|
-
|
|
19
|
-
# Optional — PR behavior
|
|
20
|
-
# @verndale/ai-pr — PR_BASE_BRANCH: Base branch to merge into (default main).
|
|
21
|
-
# PR_BASE_BRANCH=main
|
|
22
|
-
|
|
23
|
-
# @verndale/ai-pr — PR_DRAFT: If true (default), new PRs are drafts.
|
|
24
|
-
# PR_DRAFT=true
|
|
25
|
-
|
|
26
|
-
# Optional — AI summary + labels (when PR_AI=true)
|
|
27
|
-
# @verndale/ai-pr — PR_AI: Set true to enable AI summary and optional labels/checklist.
|
|
28
|
-
# PR_AI=true
|
|
29
|
-
|
|
30
|
-
# @verndale/ai-pr — PR_AI_ENDPOINT: AI API URL when PR_AI is true (e.g. OpenAI Responses endpoint).
|
|
31
|
-
# PR_AI_ENDPOINT=https://api.openai.com/v1/responses
|
|
32
|
-
|
|
33
|
-
# @verndale/ai-pr — PR_AI_API_KEY: Bearer token for the AI API when PR_AI is true.
|
|
34
|
-
# PR_AI_API_KEY=
|
|
35
|
-
|
|
36
|
-
# @verndale/ai-pr — PR_AI_MODEL: Model id (default string default).
|
|
37
|
-
# PR_AI_MODEL=default
|
|
38
|
-
|
package/README.md
CHANGED
|
@@ -2,10 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
AI-assisted [Conventional Commits](https://www.conventionalcommits.org/) with **bundled [commitlint](https://commitlint.js.org/)** so generated messages match the same rules enforced in hooks.
|
|
4
4
|
|
|
5
|
+
---
|
|
6
|
+
|
|
5
7
|
## Requirements
|
|
6
8
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
+
| | |
|
|
10
|
+
| --- | --- |
|
|
11
|
+
| **Node.js** | `>=24.14.0` |
|
|
12
|
+
| **Package manager** | This repo pins **pnpm** in `package.json`. Enable with [Corepack](https://nodejs.org/api/corepack.html): `corepack enable`. |
|
|
13
|
+
|
|
14
|
+
---
|
|
9
15
|
|
|
10
16
|
## Install
|
|
11
17
|
|
|
@@ -13,48 +19,118 @@ AI-assisted [Conventional Commits](https://www.conventionalcommits.org/) with **
|
|
|
13
19
|
pnpm add -D @verndale/ai-commit
|
|
14
20
|
```
|
|
15
21
|
|
|
16
|
-
|
|
22
|
+
**npm** and **yarn** work too (`npm install -D @verndale/ai-commit`). Where this doc says `pnpm exec`, use your tool’s equivalent (`npx`, `yarn exec`, etc.).
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Setup
|
|
27
|
+
|
|
28
|
+
Do these **in order** from your **git repository root** (the directory that contains `package.json`).
|
|
29
|
+
|
|
30
|
+
### 1. Install the package
|
|
31
|
+
|
|
32
|
+
See [Install](#install).
|
|
33
|
+
|
|
34
|
+
### 2. Run init
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
pnpm exec ai-commit init
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
**What init does (by default):**
|
|
41
|
+
|
|
42
|
+
| Action | Detail |
|
|
43
|
+
| --- | --- |
|
|
44
|
+
| Env files | Merges **`.env`** and **`.env-example`**; creates **`.env-example`** from the bundled template if missing. Template reference: [`.env-example`](.env-example). |
|
|
45
|
+
| Husky | Runs **`npx husky@9 init`** if Husky is not present. |
|
|
46
|
+
| `package.json` | Adds missing **`commit`**, **`prepare`**, **`husky`** entries when the file exists. |
|
|
47
|
+
| Hooks | Writes **`.husky`** hook files. |
|
|
48
|
+
|
|
49
|
+
If **`package.json`** changed, run **`pnpm install`** (or `npm install`) again.
|
|
50
|
+
|
|
51
|
+
### 3. Add your API key
|
|
52
|
+
|
|
53
|
+
Set **`OPENAI_API_KEY`** in **`.env`** and/or **`.env.local`**. Duplicate keys: **`.env.local`** wins.
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
### Init: flags and shortcuts
|
|
58
|
+
|
|
59
|
+
| Flag | Use when |
|
|
60
|
+
| --- | --- |
|
|
61
|
+
| *(none)* | Full setup: env files + Husky + hooks + `package.json` updates (when applicable). |
|
|
62
|
+
| `--env-only` | You only want env / **`.env-example`** updates—no Git hooks. |
|
|
63
|
+
| `--husky` | Hooks + Husky only; skips **`package.json`** changes. Combine with **`--workspace`** if you need **`package.json`** merged again. |
|
|
64
|
+
| `--force` | Replace **`.env`** and **`.env-example`** with the bundled template **(destructive)** and/or overwrite existing Husky hook files. |
|
|
65
|
+
|
|
66
|
+
**Edge cases**
|
|
67
|
+
|
|
68
|
+
| Situation | Behavior |
|
|
69
|
+
| --- | --- |
|
|
70
|
+
| Not in a git repo | Init updates env files only and reports that Git/Husky were skipped. |
|
|
71
|
+
| Template filename | The published file is **`.env-example`** (hyphen), not **`.env.example`**. |
|
|
72
|
+
| Without **`--force`** | Missing **`.env-example`** is created; otherwise missing ai-commit keys are **appended** to **`.env`** (and the example file) without wiping the file. |
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
### Setup — command cheat sheet
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
pnpm add -D @verndale/ai-commit
|
|
80
|
+
pnpm exec ai-commit init
|
|
81
|
+
# Set OPENAI_API_KEY in .env or .env.local
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Optional variants:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
pnpm exec ai-commit init --env-only
|
|
88
|
+
pnpm exec ai-commit init --husky
|
|
89
|
+
pnpm exec ai-commit init --force
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
---
|
|
17
93
|
|
|
18
|
-
##
|
|
94
|
+
## Environment variables
|
|
19
95
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
3. **Secrets** — Set **`OPENAI_API_KEY`** in `.env` and/or `.env.local` (`.env.local` overrides `.env` for duplicate keys).
|
|
96
|
+
| Variable | Notes |
|
|
97
|
+
| --- | --- |
|
|
98
|
+
| **`OPENAI_API_KEY`** | Required for **`ai-commit run`** and for AI in **`prepare-commit-msg`** when you want the model. |
|
|
99
|
+
| **`COMMIT_AI_MODEL`** | Optional; default **`gpt-4o-mini`**. |
|
|
100
|
+
| **Load order** | CLI loads **`.env`**, then **`.env.local`** (same key → `.env.local` wins). |
|
|
26
101
|
|
|
27
|
-
|
|
102
|
+
**Comments:** If another tool already documents **`OPENAI_API_KEY`** or **`COMMIT_AI_MODEL`**, **`ai-commit init`** inserts a `# @verndale/ai-commit — …` line above the assignment when that line is missing. It does not remove existing comments.
|
|
28
103
|
|
|
29
|
-
|
|
104
|
+
**Other tooling (optional):** `PR_*` for [`@verndale/ai-pr`](https://www.npmjs.com/package/@verndale/ai-pr) and **`pnpm run pr:create`** / PR workflows; `RELEASE_NOTES_AI_*` for [`tools/semantic-release-notes.cjs`](./tools/semantic-release-notes.cjs). Use a GitHub PAT as **`GH_TOKEN`** or **`GITHUB_TOKEN`** when calling the GitHub API outside Actions.
|
|
30
105
|
|
|
31
|
-
|
|
32
|
-
- **Shared env vars** — If another tool already documents **`OPENAI_API_KEY`** or **`COMMIT_AI_MODEL`**, **`ai-commit init`** adds its own `# @verndale/ai-commit — …` line immediately above the assignment when missing; it does not remove or replace existing comment lines.
|
|
33
|
-
- The CLI loads **`.env`** then **`.env.local`** from the current working directory (project root); values in `.env.local` override `.env` for the same key.
|
|
34
|
-
- **Optional tooling:** `PR_*` env vars for [`@verndale/ai-pr`](https://www.npmjs.com/package/@verndale/ai-pr) (`pnpm run pr:create` in this repo) / the **Create or update PR** workflow; `RELEASE_NOTES_AI_*` for [`tools/semantic-release-notes.cjs`](./tools/semantic-release-notes.cjs). Use a GitHub PAT as **`GH_TOKEN`** (or `GITHUB_TOKEN`) when calling the GitHub API outside Actions.
|
|
106
|
+
---
|
|
35
107
|
|
|
36
108
|
## Commit policy (v2)
|
|
37
109
|
|
|
38
|
-
- **Mandatory scope** —
|
|
110
|
+
- **Mandatory scope** — Headers are `type(scope): Subject` (or `type(scope)!:` when breaking). Scope comes from staged paths ([`lib/core/message-policy.js`](lib/core/message-policy.js)), not from the model, with fallback from `package.json` (e.g. `ai-commit`).
|
|
39
111
|
- **Types** — `build`, `chore`, `ci`, `docs`, `feat`, `fix`, `perf`, `refactor`, `revert`, `style`, `test`.
|
|
40
112
|
- **Subject** — Imperative, Beams-style (first word capitalized), max **50** characters, no trailing period.
|
|
41
|
-
- **Body / footer** — Wrap
|
|
113
|
+
- **Body / footer** — Wrap at **72** characters when present.
|
|
42
114
|
- **Issues** — If branch or diff mentions `#123`, footers may add `Refs #n` / `Closes #n` (no invented numbers).
|
|
43
|
-
- **Breaking changes** — Only when policy detects governance-related files (commitlint, Husky, this package’s rules/preset); otherwise `!` and `BREAKING CHANGE:`
|
|
44
|
-
- **Staged diff for AI** — Lockfile and common binary globs are
|
|
115
|
+
- **Breaking changes** — Only when policy detects governance-related files (commitlint, Husky, this package’s rules/preset); otherwise `!` and `BREAKING CHANGE:` are stripped.
|
|
116
|
+
- **Staged diff for AI** — Lockfile and common binary globs are excluded from the text sent to the model ([`lib/core/git.js`](lib/core/git.js)); path detection still uses the full staged file list.
|
|
117
|
+
|
|
118
|
+
**Semver:** v2 tightens commitlint (mandatory scope, stricter lengths). If you `extends` this preset, review [`lib/rules.js`](lib/rules.js) and adjust overrides as needed.
|
|
45
119
|
|
|
46
|
-
|
|
120
|
+
---
|
|
47
121
|
|
|
48
|
-
##
|
|
122
|
+
## CLI reference
|
|
49
123
|
|
|
50
124
|
| Command | Purpose |
|
|
51
125
|
| --- | --- |
|
|
52
|
-
|
|
|
53
|
-
|
|
|
54
|
-
|
|
|
55
|
-
|
|
|
126
|
+
| **`ai-commit run`** | Build a message from the staged diff and run **`git commit`**. |
|
|
127
|
+
| **`ai-commit init`** | Env merge (including **`.env-example`**), Husky if needed, **`package.json`** when present, hooks. See [flags](#init-flags-and-shortcuts). |
|
|
128
|
+
| **`ai-commit prepare-commit-msg <file> [source]`** | Hook: fill an empty message; skips `merge` / `squash`. |
|
|
129
|
+
| **`ai-commit lint --edit <file>`** | Hook: commitlint with this package’s default config. |
|
|
130
|
+
|
|
131
|
+
---
|
|
56
132
|
|
|
57
|
-
## package.json
|
|
133
|
+
## `package.json` script (example)
|
|
58
134
|
|
|
59
135
|
```json
|
|
60
136
|
{
|
|
@@ -64,9 +140,11 @@ Use **`ai-commit init --force`** to replace **`.env`** and **`.env-example`** wi
|
|
|
64
140
|
}
|
|
65
141
|
```
|
|
66
142
|
|
|
143
|
+
---
|
|
144
|
+
|
|
67
145
|
## Husky (manual setup)
|
|
68
146
|
|
|
69
|
-
**`pnpm exec ai-commit init`**
|
|
147
|
+
**`pnpm exec ai-commit init`** configures Husky for you. To add hooks by hand, install Husky (`husky` + `"prepare": "husky"` in `package.json` if needed), then add:
|
|
70
148
|
|
|
71
149
|
**`.husky/prepare-commit-msg`**
|
|
72
150
|
|
|
@@ -86,15 +164,17 @@ pnpm exec ai-commit prepare-commit-msg "$1" "$2"
|
|
|
86
164
|
pnpm exec ai-commit lint --edit "$1"
|
|
87
165
|
```
|
|
88
166
|
|
|
89
|
-
Hooks
|
|
167
|
+
Hooks from **`init`** use **`pnpm exec ai-commit`** when **`pnpm-lock.yaml`** exists; otherwise **`npx --no ai-commit`**. Edit the files if you use another runner.
|
|
168
|
+
|
|
169
|
+
**Already using Husky?** If **`.husky/_/husky.sh`** exists, **`init`** does not run **`npx husky@9 init`**. **`package.json`** is only amended for missing **`commit`**, **`prepare`**, or **`devDependencies.husky`**. Existing **`.husky/prepare-commit-msg`** and **`.husky/commit-msg`** are not overwritten unless you use **`ai-commit init --force`**.
|
|
90
170
|
|
|
91
|
-
|
|
171
|
+
---
|
|
92
172
|
|
|
93
173
|
## commitlint without a second install
|
|
94
174
|
|
|
95
|
-
Use
|
|
175
|
+
Use **`ai-commit lint --edit`** from hooks (see above).
|
|
96
176
|
|
|
97
|
-
To **extend** the
|
|
177
|
+
To **extend** the preset in your own `commitlint.config.js`:
|
|
98
178
|
|
|
99
179
|
```js
|
|
100
180
|
module.exports = {
|
|
@@ -105,12 +185,14 @@ module.exports = {
|
|
|
105
185
|
};
|
|
106
186
|
```
|
|
107
187
|
|
|
108
|
-
|
|
188
|
+
Shared constants (types, line limits):
|
|
109
189
|
|
|
110
190
|
```js
|
|
111
191
|
const rules = require("@verndale/ai-commit/rules");
|
|
112
192
|
```
|
|
113
193
|
|
|
194
|
+
---
|
|
195
|
+
|
|
114
196
|
## Development (this repository)
|
|
115
197
|
|
|
116
198
|
```bash
|
|
@@ -118,46 +200,50 @@ corepack enable
|
|
|
118
200
|
pnpm install
|
|
119
201
|
```
|
|
120
202
|
|
|
121
|
-
Copy **`.env-example`** to `.env`
|
|
203
|
+
Copy **`.env-example`** to `.env` / `.env.local` and set **`OPENAI_API_KEY`**. After staging, **`pnpm commit`** runs **`node ./bin/cli.js run`**; published installs use the **`ai-commit`** binary under **`node_modules/.bin`**. Local **`.husky`** hooks use **`pnpm exec ai-commit`**.
|
|
122
204
|
|
|
123
205
|
### Repository automation
|
|
124
206
|
|
|
125
207
|
| Workflow | Trigger | Purpose |
|
|
126
208
|
| --- | --- | --- |
|
|
127
|
-
| [`.github/workflows/commitlint.yml`](./.github/workflows/commitlint.yml) | PRs to `main`, pushes to non-`main`
|
|
128
|
-
| [`.github/workflows/pr.yml`](./.github/workflows/pr.yml) | Pushes (not `main`)
|
|
129
|
-
| [`.github/workflows/release.yml`](./.github/workflows/release.yml) | Push to **`main`**
|
|
209
|
+
| [`.github/workflows/commitlint.yml`](./.github/workflows/commitlint.yml) | PRs to `main`, pushes to non-`main` | Commitlint on PR range or last push |
|
|
210
|
+
| [`.github/workflows/pr.yml`](./.github/workflows/pr.yml) | Pushes (not `main`), `workflow_dispatch` | **`pnpm run pr:create`** ([**`@verndale/ai-pr`**](https://www.npmjs.com/package/@verndale/ai-pr)); workflow sets **`PR_HEAD_BRANCH`** / **`PR_BASE_BRANCH`**. Use secret **`PR_BOT_TOKEN`** if branch protection requires it. |
|
|
211
|
+
| [`.github/workflows/release.yml`](./.github/workflows/release.yml) | Push to **`main`** | **semantic-release** — version, `CHANGELOG.md`, tag, npm publish, GitHub Release |
|
|
130
212
|
|
|
131
|
-
|
|
213
|
+
**Local `pnpm run pr:create`:** set **`GH_TOKEN`** / **`GITHUB_TOKEN`** and **`PR_BASE_BRANCH`** / **`PR_HEAD_BRANCH`** as needed.
|
|
214
|
+
|
|
215
|
+
---
|
|
132
216
|
|
|
133
217
|
## Publishing (maintainers)
|
|
134
218
|
|
|
135
|
-
Releases
|
|
219
|
+
Releases run via **[semantic-release](https://github.com/semantic-release/semantic-release)** on push to **`main`** ([`.releaserc.json`](.releaserc.json), [`tools/semantic-release-notes.cjs`](./tools/semantic-release-notes.cjs)).
|
|
136
220
|
|
|
137
221
|
### Secrets and registry
|
|
138
222
|
|
|
139
|
-
- **`NPM_TOKEN`** (
|
|
140
|
-
- **If the job fails with `EOTP` / “
|
|
141
|
-
- **Classic token:** npmjs.com → **Access Tokens** → **Generate New Token** (classic) → type **Automation** (not “Publish”). Store
|
|
142
|
-
- **Granular token:** **New Granular Access Token** →
|
|
143
|
-
-
|
|
144
|
-
- **`GITHUB_TOKEN`** —
|
|
223
|
+
- **`NPM_TOKEN`** (repo or org secret) — must **`npm publish`** in CI **without** an interactive OTP. The Release workflow sets **`NPM_TOKEN`** and **`NODE_AUTH_TOKEN`** from it.
|
|
224
|
+
- **If the job fails with `EOTP` / “one-time password”:** 2FA is enforced on publish and the token cannot skip OTP. Fix in one of these ways:
|
|
225
|
+
- **Classic token:** [npmjs.com](https://www.npmjs.com/) → **Access Tokens** → **Generate New Token** (classic) → type **Automation** (not “Publish”). Store as **`NPM_TOKEN`**.
|
|
226
|
+
- **Granular token:** **New Granular Access Token** → enable **Bypass two-factor authentication (2FA)**. Under **Packages and scopes**, **Read and write** for **`@verndale/ai-commit`**. Leave **Allowed IP ranges** empty unless required (Actions egress is not a single fixed IP).
|
|
227
|
+
- Or finish **[Trusted Publishing](https://docs.npmjs.com/trusted-publishers)** for this repo and package (OIDC); you may still need npm-side setup—see npm’s docs for your account.
|
|
228
|
+
- **`GITHUB_TOKEN`** — Provided by Actions. Checkout and **`@semantic-release/git`** use **`SEMANTIC_RELEASE_TOKEN`** when set; otherwise **`GITHUB_TOKEN`**.
|
|
145
229
|
|
|
146
|
-
**npm provenance:** [`.releaserc.json`](
|
|
230
|
+
**npm provenance:** [`.releaserc.json`](.releaserc.json) sets **`"provenance": true`** on **`@semantic-release/npm`**, which matches **npm Trusted Publishing** from this GitHub repo. On [npmjs.com](https://www.npmjs.com/), enable **Trusted Publishing** for this package linked to **`verndale/ai-commit`** (or your fork). If publish fails until that works, finish Trusted Publishing or temporarily set **`"provenance": false`** in **`.releaserc.json`** (you lose the provenance badge).
|
|
147
231
|
|
|
148
|
-
### Branch protection
|
|
232
|
+
### Branch protection
|
|
149
233
|
|
|
150
|
-
semantic-release pushes a **release commit** and **tag** back to
|
|
234
|
+
semantic-release pushes a **release commit** and **tag** back to **`main`** via **`@semantic-release/git`**. If **`main`** is protected and the default token cannot push, either allow **GitHub Actions** to bypass protection for this repository, or add a PAT (classic: **`repo`**; fine-grained: **Contents** read/write) as **`SEMANTIC_RELEASE_TOKEN`**. The Release workflow passes **`SEMANTIC_RELEASE_TOKEN || GITHUB_TOKEN`** to checkout and to semantic-release as **`GITHUB_TOKEN`**.
|
|
151
235
|
|
|
152
236
|
### Commits that produce releases
|
|
153
237
|
|
|
154
|
-
**Conventional Commits** on
|
|
238
|
+
**Conventional Commits** on **`main`** drive the analyzer (patch / minor / major) using each commit’s **first line**; PR bodies do not replace that.
|
|
239
|
+
|
|
240
|
+
With default [`.releaserc.json`](.releaserc.json) (no custom **`releaseRules`**), types like **`chore`**, **`docs`**, **`ci`**, **`style`**, **`test`**, **`build`** do **not** bump version or update **`CHANGELOG.md`**. For user-facing releases, use **`feat`**, **`fix`**, **`perf`**, **`revert`**, or breaking markers. With **squash merge**, the merged message is usually the **PR title**—keep it commitlint-clean.
|
|
155
241
|
|
|
156
|
-
|
|
242
|
+
To release from **`chore`**/**`docs`**-only merges, maintainers can add **`releaseRules`** to **`@semantic-release/commit-analyzer`** in **`.releaserc.json`**; the default skips those types so releases stay signal-heavy.
|
|
157
243
|
|
|
158
|
-
|
|
244
|
+
Tag-only npm publish was removed in favor of this flow to avoid double publishes. **Local try:** `pnpm release` (needs tokens and git state; use a fork or **`--dry-run`** as appropriate).
|
|
159
245
|
|
|
160
|
-
|
|
246
|
+
---
|
|
161
247
|
|
|
162
248
|
## License
|
|
163
249
|
|