@releasekit/version 0.1.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.
@@ -0,0 +1,501 @@
1
+ # Versioning Strategies and Concepts
2
+
3
+ `package-versioner` offers flexible ways to determine the next version for your project based on its history and your configuration.
4
+
5
+ ## How the Next Version is Calculated
6
+
7
+ There are two primary methods the tool uses to decide the version bump (e.g., patch, minor, major), configured via the `versionStrategy` option in `version.config.json`:
8
+
9
+ ### 1. Conventional Commits (`versionStrategy: "conventional"`)
10
+
11
+ This is the default strategy. `package-versioner` analyzes Git commit messages since the last Git tag that follows semver patterns. It uses the [conventional-commits](https://www.conventionalcommits.org/) specification to determine the bump:
12
+
13
+ - **Patch Bump (e.g., 1.2.3 -> 1.2.4):** Triggered by `fix:` commit types.
14
+ - **Minor Bump (e.g., 1.2.3 -> 1.3.0):** Triggered by `feat:` commit types.
15
+ - **Major Bump (e.g., 1.2.3 -> 2.0.0):** Triggered by commits with `BREAKING CHANGE:` in the footer or `feat!:`, `fix!:` etc. in the header.
16
+
17
+ The specific preset used for analysis (e.g., "angular", "conventional") can be set using the `preset` option in `version.config.json`.
18
+
19
+ **Format:** `<type>(<scope>): <subject>`
20
+
21
+ `<scope>` is optional.
22
+
23
+ **Example Commit Types:**
24
+
25
+ - `feat:` (new feature for the user)
26
+ - `fix:` (bug fix for the user)
27
+ - `docs:` (changes to the documentation)
28
+ - `style:` (formatting, missing semi-colons, etc; no production code change)
29
+ - `refactor:` (refactoring production code, e.g. renaming a variable)
30
+ - `test:` (adding missing tests, refactoring tests; no production code change)
31
+ - `chore:` (updating build tasks etc; no production code change)
32
+
33
+ **References:**
34
+
35
+ - [https://www.conventionalcommits.org/](https://www.conventionalcommits.org/)
36
+ - [https://github.com/conventional-changelog/conventional-changelog](https://github.com/conventional-changelog/conventional-changelog)
37
+
38
+ ### 2. Branch Pattern (`versionStrategy: "branchPattern"`)
39
+
40
+ This strategy uses the name of the current Git branch (or the most recently merged branch matching a pattern, if applicable) to determine the version bump.
41
+
42
+ You define patterns in the `branchPattern` array in `version.config.json`. Each pattern is a string like `"prefix:bumptype"`.
43
+
44
+ **Example `version.config.json`:**
45
+
46
+ ```json
47
+ {
48
+ "versionStrategy": "branchPattern",
49
+ "branchPattern": [
50
+ "feature:minor",
51
+ "hotfix:patch",
52
+ "fix:patch",
53
+ "release:major"
54
+ ],
55
+ "baseBranch": "main"
56
+ }
57
+ ```
58
+
59
+ **How it works:**
60
+
61
+ 1. The tool checks the current branch name.
62
+ 2. It might also look for the most recently merged branch into `baseBranch` that matches any pattern in `branchPattern`.
63
+ 3. It compares the relevant branch name (current or last merged) against the prefixes in `branchPattern`.
64
+ 4. If a match is found (e.g., current branch is `feature/add-login`), it applies the corresponding bump type (`minor` in this case).
65
+
66
+ This allows you to enforce version bumps based on your branching workflow (e.g., all branches starting with `feature/` result in a minor bump).
67
+
68
+ ## Package Type Support
69
+
70
+ `package-versioner` supports both JavaScript/TypeScript projects using `package.json` and Rust projects using `Cargo.toml`:
71
+
72
+ ### JavaScript/TypeScript Projects
73
+
74
+ For JavaScript/TypeScript projects, the tool looks for and updates the `version` field in `package.json` files according to the versioning strategies described above.
75
+
76
+ ### Rust Projects
77
+
78
+ For Rust projects, the tool looks for and updates the `package.version` field in `Cargo.toml` files using the same versioning strategies.
79
+
80
+ ### Mixed Projects with Both Manifests
81
+
82
+ When both `package.json` and `Cargo.toml` exist in the same directory, `package-versioner` will:
83
+
84
+ 1. Update both manifest files independently with the same calculated version
85
+ 2. First check `package.json` for the current version (when no tags exist)
86
+ 3. Fall back to checking `Cargo.toml` only if `package.json` doesn't exist or doesn't have a version
87
+
88
+ This allows you to maintain consistent versioning across JavaScript and Rust components in the same package.
89
+
90
+ ## Version Source Selection
91
+
92
+ `package-versioner` uses a smart version source selection strategy to determine the base version for calculating the next version:
93
+
94
+ 1. First, it checks for Git tags:
95
+ - In normal mode: Uses the latest reachable tag, falling back to unreachable tags if needed
96
+ - In strict mode (`--strict-reachable`): Only uses reachable tags
97
+
98
+ 2. Then, it checks manifest files (package.json, Cargo.toml):
99
+ - Reads version from package.json if it exists
100
+ - Falls back to Cargo.toml if package.json doesn't exist or has no version
101
+
102
+ 3. Finally, it compares the versions:
103
+ - If both Git tag and manifest versions exist, it uses the newer version
104
+ - If the versions are equal, it prefers the Git tag for better history tracking
105
+ - If only one source has a version, it uses that
106
+ - If no version is found, it uses the default initial version (0.1.0)
107
+
108
+ This strategy ensures that:
109
+ - Version numbers never go backwards
110
+ - Git history is respected when possible
111
+ - Manifest files are considered as valid version sources
112
+ - The tool always has a valid base version to work from
113
+
114
+ For example:
115
+ ```
116
+ Scenario 1:
117
+ - Git tag: v1.0.0
118
+ - package.json: 1.1.0
119
+ Result: Uses 1.1.0 as base (package.json is newer)
120
+
121
+ Scenario 2:
122
+ - Git tag: v1.0.0
123
+ - package.json: 1.0.0
124
+ Result: Uses v1.0.0 as base (versions equal, prefer Git)
125
+
126
+ Scenario 3:
127
+ - Git tag: unreachable v2.0.0
128
+ - package.json: 1.0.0
129
+ Result: Uses 2.0.0 as base in normal mode (unreachable tag is newer)
130
+ Uses 1.0.0 as base in strict mode (unreachable tag ignored)
131
+ ```
132
+
133
+ ### Version Mismatch Detection
134
+
135
+ When Git tags and manifest versions diverge significantly, it can lead to unexpected version bumps. A common scenario is when a release is reverted but its Git tag is not deleted — the tool sees the tag as the latest version and bumps from there.
136
+
137
+ For example:
138
+ ```
139
+ - Git tag: v1.0.0 (from a reverted release)
140
+ - package.json: 1.0.0-beta.3
141
+ - Without mismatch detection: Uses v1.0.0 as base, next release bumps to v2.0.0
142
+ ```
143
+
144
+ The `mismatchStrategy` option controls how these situations are handled:
145
+
146
+ | Strategy | Behavior |
147
+ |----------|----------|
148
+ | `"error"` (default) | Throws an error and stops execution, forcing the user to resolve the mismatch |
149
+ | `"warn"` | Logs a warning describing the mismatch, then continues with the higher version |
150
+ | `"prefer-package"` | Uses the package.json version as the base when a mismatch is detected |
151
+ | `"prefer-git"` | Uses the git tag version as the base when a mismatch is detected |
152
+ | `"ignore"` | Silently continues with the higher version (pre-v0.9.4 behavior) |
153
+
154
+ Mismatches are detected in the following cases:
155
+ - Git tag is a stable release but package.json is a prerelease of the same major version (e.g., tag `1.0.0` vs package `1.0.0-beta.3`)
156
+ - Git tag is ahead by a major or minor version (e.g., tag `2.0.0` vs package `1.0.0`)
157
+ - Git tag is a prerelease but package.json is a stable release (e.g., tag `1.0.0-beta.1` vs package `1.0.0`)
158
+
159
+ Configure it in `version.config.json`:
160
+ ```json
161
+ {
162
+ "mismatchStrategy": "prefer-package"
163
+ }
164
+ ```
165
+
166
+ ## Package Targeting in Monorepos
167
+
168
+ When working with monorepos, you can control which packages are processed for versioning using the `packages` configuration option. This provides flexible targeting with support for various pattern types.
169
+
170
+ ### Targeting Patterns
171
+
172
+ #### Exact Package Names
173
+ Target specific packages by their exact names:
174
+ ```json
175
+ {
176
+ "packages": ["@mycompany/core", "@mycompany/utils", "standalone-package"]
177
+ }
178
+ ```
179
+
180
+ #### Scope Wildcards
181
+ Target all packages within a specific scope:
182
+ ```json
183
+ {
184
+ "packages": ["@mycompany/*"]
185
+ }
186
+ ```
187
+ This will match all packages whose names start with `@mycompany/`.
188
+
189
+ #### Global Wildcard
190
+ Target all packages in the workspace:
191
+ ```json
192
+ {
193
+ "packages": ["*"]
194
+ }
195
+ ```
196
+
197
+ #### Mixed Patterns
198
+ Target different types of packages using a combination of patterns:
199
+ ```json
200
+ {
201
+ "packages": ["@mycompany/*", "@utils/logger", "legacy-package"]
202
+ }
203
+ ```
204
+
205
+ ### Skip Patterns
206
+
207
+ The `skip` configuration option allows you to exclude specific packages from versioning using the same pattern matching capabilities as package targeting.
208
+
209
+ #### Pattern Types
210
+
211
+ 1. **Exact Package Names**
212
+ ```json
213
+ {
214
+ "skip": ["@internal/docs", "test-utils"]
215
+ }
216
+ ```
217
+
218
+ 2. **Scope Wildcards**
219
+ ```json
220
+ {
221
+ "skip": ["@internal/*"]
222
+ }
223
+ ```
224
+ This will skip all packages whose names start with `@internal/`.
225
+
226
+ 3. **Path Patterns**
227
+ ```json
228
+ {
229
+ "skip": ["packages/**/test-*", "examples/**/*"]
230
+ }
231
+ ```
232
+ This will skip packages matching the specified path patterns.
233
+
234
+ 4. **Mixed Patterns**
235
+ ```json
236
+ {
237
+ "skip": ["@internal/*", "test-*", "packages/examples/**/*"]
238
+ }
239
+ ```
240
+
241
+ #### Skip Pattern Priority
242
+
243
+ Skip patterns take precedence over include patterns. If a package matches both a pattern in `packages` and a pattern in `skip`, it will be excluded from versioning.
244
+
245
+ Example:
246
+ ```json
247
+ {
248
+ "packages": ["@company/*"],
249
+ "skip": ["@company/internal-*"]
250
+ }
251
+ ```
252
+ In this case, all packages under the `@company` scope will be versioned except those starting with `@company/internal-`.
253
+
254
+ ### Behaviour
255
+
256
+ - **When `packages` is specified**: Only packages matching those patterns will be processed for versioning
257
+ - **When `packages` is empty or not specified**: All workspace packages will be processed
258
+ - **Error handling**: If no packages match the specified patterns, a warning is displayed
259
+
260
+ ### Excluding Packages
261
+
262
+ Use the `skip` option to exclude specific packages from processing:
263
+ ```json
264
+ {
265
+ "packages": ["@mycompany/*"],
266
+ "skip": ["@mycompany/deprecated-package"]
267
+ }
268
+ ```
269
+
270
+ This configuration will process all packages in the `@mycompany` scope except for `@mycompany/deprecated-package`.
271
+
272
+ **Note**: Your workspace configuration (pnpm-workspace.yaml, package.json workspaces, etc.) determines which packages are available in your workspace, but the `packages` option directly controls which ones get versioned.
273
+
274
+ ## Tag Templates and Configuration
275
+
276
+ `package-versioner` provides flexible configuration for how Git tags are formatted, allowing you to customize the tag structure for both single package repositories and monorepos.
277
+
278
+ ### Tag Template Configuration
279
+
280
+ You can customize how tags are formatted using the following configuration options in `version.config.json`:
281
+
282
+ ```json
283
+ {
284
+ "versionPrefix": "v",
285
+ "tagTemplate": "${prefix}${version}",
286
+ "packageSpecificTags": false
287
+ }
288
+ ```
289
+
290
+ - **versionPrefix**: The prefix used for all version numbers in tags (default: `"v"`)
291
+ - **tagTemplate**: The template for Git tags (default: `"${prefix}${version}"`)
292
+ - **packageSpecificTags**: Whether to enable package-specific tagging behaviour (default: `false`)
293
+
294
+ ### Available Template Variables
295
+
296
+ The tag template supports the following variables:
297
+
298
+ - `${prefix}`: Replaced with the value of `versionPrefix`
299
+ - `${version}`: Replaced with the calculated version number
300
+ - `${packageName}`: Replaced with the package name (only populated when `packageSpecificTags` is `true`)
301
+
302
+ ### How Package-Specific Tagging Works
303
+
304
+ The `packageSpecificTags` option controls whether the `${packageName}` variable is populated in your template:
305
+
306
+ - **When `packageSpecificTags` is `false`**: The `${packageName}` variable is empty, so use templates like `${prefix}${version}`
307
+ - **When `packageSpecificTags` is `true`**: The `${packageName}` variable contains the actual package name
308
+
309
+ ### Examples
310
+
311
+ #### Global Versioning (Default)
312
+ ```json
313
+ {
314
+ "versionPrefix": "v",
315
+ "tagTemplate": "${prefix}${version}",
316
+ "packageSpecificTags": false
317
+ }
318
+ ```
319
+ This produces tags like `v1.2.3` for all packages.
320
+
321
+ #### Package-Specific Versioning
322
+ ```json
323
+ {
324
+ "versionPrefix": "v",
325
+ "tagTemplate": "${packageName}@${prefix}${version}",
326
+ "packageSpecificTags": true
327
+ }
328
+ ```
329
+ This produces tags like `@scope/package-name@v1.2.3` for each package.
330
+
331
+ #### Custom Tag Format Examples
332
+ ```json
333
+ {
334
+ "versionPrefix": "",
335
+ "tagTemplate": "release-${version}",
336
+ "packageSpecificTags": false
337
+ }
338
+ ```
339
+ This would produce tags like `release-1.2.3` instead of `v1.2.3`.
340
+
341
+ ```json
342
+ {
343
+ "versionPrefix": "v",
344
+ "tagTemplate": "${packageName}-${prefix}${version}",
345
+ "packageSpecificTags": true
346
+ }
347
+ ```
348
+ This would produce package tags like `@scope/package-name-v1.2.3` instead of `@scope/package-name@v1.2.3`.
349
+
350
+ ### Behaviour in Different Modes
351
+
352
+ - **Synced Mode with Single Package**: When `packageSpecificTags` is `true`, the package name is used even though all packages are versioned together
353
+ - **Synced Mode with Multiple Packages**: Package names are not used regardless of the `packageSpecificTags` setting
354
+ - **Async Mode**: Each package gets its own tag when `packageSpecificTags` is enabled
355
+
356
+ ## Troubleshooting Template Configuration
357
+
358
+ `package-versioner` provides helpful warnings when template configurations don't match your project setup. Here are common issues and their solutions:
359
+
360
+ ### Template Contains ${packageName} but No Package Name Available
361
+
362
+ If you see this warning, it means your template includes `${packageName}` but the tool cannot determine a package name for the current context.
363
+
364
+ **Example Warning:**
365
+ ```
366
+ Warning: Your tagTemplate contains ${packageName} but no package name is available.
367
+ This will result in an empty package name in the tag (e.g., "@v1.0.0" instead of "my-package@v1.0.0").
368
+
369
+ To fix this:
370
+ • If using sync mode: Set "packageSpecificTags": true in your config to enable package names in tags
371
+ • If you want global tags: Remove ${packageName} from your tagTemplate (e.g., use "${prefix}${version}")
372
+ • If using single/async mode: Ensure your package.json has a valid "name" field
373
+ ```
374
+
375
+ **Solutions:**
376
+
377
+ 1. **For Synced Mode with Package Names**: Enable package-specific tags
378
+ ```json
379
+ {
380
+ "sync": true,
381
+ "packageSpecificTags": true,
382
+ "tagTemplate": "${packageName}@${prefix}${version}"
383
+ }
384
+ ```
385
+
386
+ 2. **For Global Tags**: Remove `${packageName}` from your template
387
+ ```json
388
+ {
389
+ "tagTemplate": "${prefix}${version}",
390
+ "packageSpecificTags": false
391
+ }
392
+ ```
393
+
394
+ 3. **For Single/Async Mode**: Ensure your `package.json` has a valid `name` field
395
+ ```json
396
+ {
397
+ "name": "my-package",
398
+ "version": "1.0.0"
399
+ }
400
+ ```
401
+
402
+ ### Common Template Patterns
403
+
404
+ Here are some common template patterns and when to use them:
405
+
406
+ | Pattern | Use Case | Example Output |
407
+ |---------|----------|----------------|
408
+ | `"${prefix}${version}"` | Global versioning, all packages get same tag | `v1.2.3` |
409
+ | `"${packageName}@${prefix}${version}"` | Package-specific versioning | `@scope/package@v1.2.3` |
410
+ | `"release-${version}"` | Custom release format | `release-1.2.3` |
411
+ | `"${packageName}-${version}"` | Simple package versioning | `@scope/package-1.2.3` |
412
+
413
+ ### Commit Message Templates
414
+
415
+ The same principles apply to `commitMessage` templates. If your commit message template includes `${packageName}`, ensure that package names are available in your current mode:
416
+
417
+ ```json
418
+ {
419
+ "commitMessage": "chore: release ${packageName}@${version}",
420
+ "packageSpecificTags": true
421
+ }
422
+ ```
423
+
424
+ For global commit messages, use templates without `${packageName}`:
425
+ ```json
426
+ {
427
+ "commitMessage": "chore: release ${version}"
428
+ }
429
+ ```
430
+
431
+ ## Monorepo Versioning Modes
432
+
433
+ While primarily used for single packages now, `package-versioner` retains options for monorepo workflows, controlled mainly by the `sync` flag in `version.config.json`.
434
+
435
+ ### Sync Mode (`sync: true`)
436
+
437
+ This is the default if the `sync` flag is present and true.
438
+
439
+ - **Behaviour:** The tool calculates **one** version bump based on the overall history (or branch pattern). This single new version is applied to **all** packages within the repository (or just the root `package.json` if not a structured monorepo). A single Git tag is created.
440
+ - **Tag Behaviour:**
441
+ - In **multi-package monorepos**: Creates global tags like `v1.2.3` regardless of `packageSpecificTags` setting
442
+ - In **single-package repositories**: Respects the `packageSpecificTags` setting - can create either `v1.2.3` or `package-name@v1.2.3`
443
+ - **Use Case:** Suitable for monorepos where all packages are tightly coupled and released together with the same version number. Also the effective mode for single-package repositories.
444
+
445
+ ### Async Mode (`sync: false`)
446
+
447
+ *(Note: This mode relies heavily on monorepo tooling and structure, like `pnpm workspaces` and correctly configured package dependencies.)*
448
+
449
+ - **Behaviour (Default - No `-t` flag):** The tool analyzes commits to determine which specific packages within the monorepo have changed since the last relevant commit/tag.
450
+ - It calculates an appropriate version bump **independently for each changed package** based on the commits affecting that package.
451
+ - Only the `package.json` files of the changed packages are updated.
452
+ - A **single commit** is created grouping all the version bumps, using the commit message template. **No Git tags are created** in this mode.
453
+ - **Use Case:** Suitable for monorepos where packages are versioned independently, but a single commit represents the batch of updates for traceability.
454
+
455
+ - **Behaviour (Targeted - With `-t` flag):** When using the `-t, --target <targets>` flag:
456
+ - Only the specified packages (respecting the `skip` list) are considered for versioning.
457
+ - It calculates an appropriate version bump **independently for each targeted package** based on its commit history.
458
+ - The `package.json` file of each successfully updated targeted package is modified.
459
+ - An **individual Git tag** (e.g., `packageName@1.2.3`) is created **for each successfully updated package** immediately after its version is bumped.
460
+ - Finally, a **single commit** is created including all the updated `package.json` files, using a summary commit message (e.g., `chore(release): pkg-a, pkg-b 1.2.3 [skip-ci]`).
461
+ - **Important:** Only package-specific tags are created. The global tag (e.g., `v1.2.3`) is **not** automatically generated in this mode. If your release process (like GitHub Releases) depends on a global tag, you'll need to create it manually in your CI/CD script *after* `package-versioner` completes.
462
+ - **Use Case:** Releasing specific packages independently while still tagging each released package individually.
463
+
464
+ ## Prerelease Handling
465
+
466
+ `package-versioner` provides flexible handling for prerelease versions, allowing both creation of prereleases and promotion to stable releases.
467
+
468
+ ### Creating Prereleases
469
+
470
+ Use the `--prerelease` flag with an identifier to create a prerelease version:
471
+
472
+ ```bash
473
+ # Create a beta prerelease
474
+ npx package-versioner --bump minor --prerelease beta
475
+ # Result: 1.0.0 -> 1.1.0-beta.0
476
+ ```
477
+
478
+ You can also set a default prerelease identifier in your `version.config.json`:
479
+
480
+ ```json
481
+ {
482
+ "prereleaseIdentifier": "beta"
483
+ }
484
+ ```
485
+
486
+ ### Promoting Prereleases to Stable Releases
487
+
488
+ When using standard bump types (`major`, `minor`, `patch`) with the `--bump` flag on a prerelease version, `package-versioner` will automatically clean the prerelease identifier:
489
+
490
+ ```bash
491
+ # Starting from version 1.0.0-beta.1
492
+ npx package-versioner --bump major
493
+ # Result: 1.0.0-beta.1 -> 2.0.0 (not 2.0.0-beta.0)
494
+ ```
495
+
496
+ This intuitive behaviour means you don't need to use an empty prerelease identifier (`--prerelease ""`) to promote a prerelease to a stable version. Simply specify the standard bump type and the tool will automatically produce a clean version number.
497
+
498
+ This applies to all standard bump types:
499
+ - `--bump major`: 1.0.0-beta.1 -> 2.0.0
500
+ - `--bump minor`: 1.0.0-beta.1 -> 1.1.0
501
+ - `--bump patch`: 1.0.0-beta.1 -> 1.0.1
package/package.json ADDED
@@ -0,0 +1,80 @@
1
+ {
2
+ "name": "@releasekit/version",
3
+ "version": "0.1.0",
4
+ "description": "A lightweight yet powerful CLI tool for automated semantic versioning based on Git history and conventional commits.",
5
+ "type": "module",
6
+ "main": "./dist/index.cjs",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "import": {
12
+ "types": "./dist/index.d.ts",
13
+ "default": "./dist/index.js"
14
+ },
15
+ "require": {
16
+ "types": "./dist/index.d.cts",
17
+ "default": "./dist/index.cjs"
18
+ }
19
+ }
20
+ },
21
+ "bin": {
22
+ "releasekit-version": "./dist/cli.js"
23
+ },
24
+ "scripts": {
25
+ "build": "tsup src/index.ts src/cli.ts --format esm,cjs --dts",
26
+ "dev": "tsup src/index.ts src/cli.ts --format esm,cjs --watch --dts",
27
+ "clean": "rm -rf dist coverage .turbo",
28
+ "test": "vitest run --dir test/unit",
29
+ "test:unit": "vitest run --coverage --dir test/unit",
30
+ "test:coverage": "vitest run --coverage --dir test/unit",
31
+ "lint": "biome check .",
32
+ "typecheck": "tsc --noEmit"
33
+ },
34
+ "keywords": ["version", "semver", "git", "package"],
35
+ "author": {
36
+ "name": "Sam Maister",
37
+ "email": "goosewobbler@protonmail.com"
38
+ },
39
+ "repository": {
40
+ "type": "git",
41
+ "url": "https://github.com/goosewobbler/releasekit",
42
+ "directory": "packages/version"
43
+ },
44
+ "license": "MIT",
45
+ "files": ["dist", "docs", "version.schema.json"],
46
+ "publishConfig": {
47
+ "access": "public"
48
+ },
49
+ "dependencies": {
50
+ "@manypkg/get-packages": "^3.1.0",
51
+ "@releasekit/config": "workspace:*",
52
+ "@releasekit/core": "workspace:*",
53
+ "@types/micromatch": "^4.0.10",
54
+ "chalk": "catalog:",
55
+ "commander": "catalog:",
56
+ "conventional-changelog-angular": "^8.1.0",
57
+ "conventional-changelog-conventional-commits": "npm:conventional-changelog-conventionalcommits@^9.0.0",
58
+ "conventional-changelog-conventionalcommits": "^9.1.0",
59
+ "conventional-commits-filter": "^5.0.0",
60
+ "conventional-recommended-bump": "^11.2.0",
61
+ "figlet": "^1.10.0",
62
+ "git-semver-tags": "^8.0.0",
63
+ "micromatch": "^4.0.8",
64
+ "semver": "catalog:",
65
+ "smol-toml": "catalog:"
66
+ },
67
+ "devDependencies": {
68
+ "@biomejs/biome": "catalog:",
69
+ "@types/figlet": "^1.5.5",
70
+ "@types/node": "catalog:",
71
+ "@types/semver": "catalog:",
72
+ "@vitest/coverage-v8": "catalog:",
73
+ "tsup": "catalog:",
74
+ "typescript": "catalog:",
75
+ "vitest": "catalog:"
76
+ },
77
+ "engines": {
78
+ "node": ">=18 || >=20"
79
+ }
80
+ }