Repository: orhun/git-cliff
Pull request #843 (2024-09-07 08:57:33)

NPM option parsing improvements and documentation improvements
> [!WARNING]
> **_This should be merged with "rebase & merge" to retain proper conventional commit history for the changelog generation_**

## Description

Couple of changes bundled:

- I got the request to implement `skip-commit` in cliff-jumper. Because the appropriate syntax for `git-cliff` is `--skip-commit SHA --skip-commit SHA --skip-commit SHA --skip-commit SHA <options options>` it is more ideal if the NodeJS code optionally takes an array of commits which can easily be parsed to CLI args in the library as opposed to janking something in cliff-jumper.
- I noticed some options from https://git-cliff.org/docs/usage/args were missing in the `Options` type so I added them.
- While doing the above I also decided to copy over all the descriptions for all the options to TSDoc comments so they are documented in the IntelliSense.
- And while doing that I noticed that `--gitea-repository` mentioned GitLab and adjusted it accordingly.

## Motivation and Context

<!--- Why is this change required? What problem does it solve? -->
<!--- If it fixes an open issue, please link to the issue here. -->

As mentioned above, I got the request to implement `--skip-commit` in cliff-jumper and needed a change for that.

## How Has This Been Tested?

I ran `yarn build` in `npm/git-cliff` then `yarn pack` to create a `package.tgz` which I then installed in `cliff-jumper`

This is when providing an array of strings:

![ishare-1725700823](https://github.com/user-attachments/assets/54392260-a302-455e-93a4-5cb55e4d18b9)


<!--- Please describe in detail how you tested your changes. -->
<!--- Include details of your testing environment, and the tests you ran to -->
<!--- see how your change affects other areas of the code, etc. -->

## Screenshots / Logs (if applicable)

## Types of Changes

<!--- What types of changes does your code introduce? Put an `x` in all the boxes that apply: -->

- [ ] Bug fix (non-breaking change which fixes an issue)
- [x] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to change)
- [x] Documentation (no code change)
- [x] Refactor (refactoring production code)
- [ ] Other <!--- (provide information) -->

## Checklist:

<!--- Go over all the following points, and put an `x` in all the boxes that apply. -->
<!--- If you're unsure about any of these, don't hesitate to ask. We're here to help! -->

- [x] My code follows the code style of this project.
- [x] I have updated the documentation accordingly.
- [x] I have formatted the code with [rustfmt](https://github.com/rust-lang/rustfmt).
- [x] I checked the lints with [clippy](https://github.com/rust-lang/rust-clippy).
- [ ] I have added tests to cover my changes.
- [ ] All new and existing tests passed.

<!--- Thank you for contributing to git-cliff! ⛰️  -->


codecov-commenter: :warning: Please install the !['codecov app svg image'](https://github.com/codecov/engineering-team/assets/152432831/e90313f4-9d3a-4b63-8b54-cfe14e7ec20d) to ensure uploads and comments are reliably processed by Codecov.

## [Codecov](https://app.codecov.io/gh/orhun/git-cliff/pull/843?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Orhun+Parmaks%C4%B1z) Report
All modified and coverable lines are covered by tests :white_check_mark:
> Project coverage is 40.19%. Comparing base [(`08e761c`)](https://app.codecov.io/gh/orhun/git-cliff/commit/08e761c20fb98730249aef2047da02a7dfca86ad?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Orhun+Parmaks%C4%B1z) to head [(`db4db47`)](https://app.codecov.io/gh/orhun/git-cliff/commit/db4db472e93cf5048493556703c84e2a1048cad8?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Orhun+Parmaks%C4%B1z).

:exclamation: Your organization needs to install the [Codecov GitHub app](https://github.com/apps/codecov/installations/select_target) to enable full functionality.

<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff             @@
##             main     #843      +/-   ##
==========================================
+ Coverage   40.13%   40.19%   +0.07%     
==========================================
  Files          20       20              
  Lines        1645     1645              
==========================================
+ Hits          660      661       +1     
+ Misses        985      984       -1     
```

| [Flag](https://app.codecov.io/gh/orhun/git-cliff/pull/843/flags?src=pr&el=flags&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Orhun+Parmaks%C4%B1z) | Coverage Δ | |
|---|---|---|
| [unit-tests](https://app.codecov.io/gh/orhun/git-cliff/pull/843/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Orhun+Parmaks%C4%B1z) | `40.19% <ø> (+0.07%)` | :arrow_up: |

Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Orhun+Parmaks%C4%B1z#carryforward-flags-in-the-pull-request-comment) to find out more.

</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/orhun/git-cliff/pull/843?dropdown=coverage&src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Orhun+Parmaks%C4%B1z).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Orhun+Parmaks%C4%B1z).


Patch:
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 08db573..3dd9f6e 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -94,6 +94,11 @@ jobs:
         with:
           command: clippy
           args: --tests --verbose -- -D warnings
+      - name: Check the pedantic lints
+        uses: actions-rs/cargo@v1
+        with:
+          command: clippy
+          args: --tests --verbose -- -W clippy::pedantic
 
   rustfmt:
     name: Formatting
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 9c8b650..3812f70 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -17,6 +17,12 @@ Note that we have a [Code of Conduct](./CODE_OF_CONDUCT.md), please follow it in
 git clone https://github.com/{username}/git-cliff && cd git-cliff
 ```
 
+To ensure the successful execution of the tests, it is essential to fetch the tags as follows:
+
+```sh
+git fetch --tags https://github.com/orhun/git-cliff
+```
+
 3. Make sure that you have [Rust](https://www.rust-lang.org/) `1.64.0` or later installed and build the project.
 
 ```sh
diff --git a/Cargo.lock b/Cargo.lock
index d21e1e0..81e0fb0 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -377,9 +377,9 @@ dependencies = [
 
 [[package]]
 name = "clap_complete"
-version = "4.5.23"
+version = "4.5.28"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "531d7959c5bbb6e266cecdd0f20213639c3a5c3e4d615f97db87661745f781ff"
+checksum = "9b378c786d3bde9442d2c6dd7e6080b2a818db2b96e30d6e7f1b6d224eb617d3"
 dependencies = [
  "clap",
 ]
@@ -1953,9 +1953,9 @@ dependencies = [
 
 [[package]]
 name = "pretty_assertions"
-version = "1.4.0"
+version = "1.4.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "af7cee1a6c8a5b9208b3cb1061f10c0cb689087b3d8ce85fb9d2dd7a29b6ba66"
+checksum = "3ae130e2f271fbc2ac3a40fb1d07180839cdbbe443c7a27e1e3c13c5cac0116d"
 dependencies = [
  "diff",
  "yansi",
@@ -3595,9 +3595,9 @@ dependencies = [
 
 [[package]]
 name = "yansi"
-version = "0.5.1"
+version = "1.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec"
+checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049"
 
 [[package]]
 name = "zerocopy"
diff --git a/examples/github-keepachangelog.toml b/examples/github-keepachangelog.toml
index 0c587aa..1a8f2f2 100644
--- a/examples/github-keepachangelog.toml
+++ b/examples/github-keepachangelog.toml
@@ -27,9 +27,9 @@ body = """
     ### {{ group | upper_first }}
     {%- for commit in commits %}
         - {{ commit.message | split(pat="\n") | first | upper_first | trim }}\
-            {% if commit.github.username %} by @{{ commit.github.username }}{%- endif -%}
-            {% if commit.github.pr_number %} in \
-            [#{{ commit.github.pr_number }}]({{ self::remote_url() }}/pull/{{ commit.github.pr_number }}) \
+            {% if commit.remote.username %} by @{{ commit.remote.username }}{%- endif -%}
+            {% if commit.remote.pr_number %} in \
+            [#{{ commit.remote.pr_number }}]({{ self::remote_url() }}/pull/{{ commit.remote.pr_number }}) \
             {%- endif -%}
     {% endfor %}
 {% endfor %}
diff --git a/examples/github.toml b/examples/github.toml
index 9853f54..9ec3e91 100644
--- a/examples/github.toml
+++ b/examples/github.toml
@@ -14,15 +14,15 @@ body = """
 
 {%- if version %} in {{ version }}{%- endif -%}
 {% for commit in commits %}
-  {% if commit.github.pr_title -%}
-    {%- set commit_message = commit.github.pr_title -%}
+  {% if commit.remote.pr_title -%}
+    {%- set commit_message = commit.remote.pr_title -%}
   {%- else -%}
     {%- set commit_message = commit.message -%}
   {%- endif -%}
   * {{ commit_message | split(pat="\n") | first | trim }}\
-    {% if commit.github.username %} by @{{ commit.github.username }}{%- endif -%}
-    {% if commit.github.pr_number %} in \
-      [#{{ commit.github.pr_number }}]({{ self::remote_url() }}/pull/{{ commit.github.pr_number }}) \
+    {% if commit.remote.username %} by @{{ commit.remote.username }}{%- endif -%}
+    {% if commit.remote.pr_number %} in \
+      [#{{ commit.remote.pr_number }}]({{ self::remote_url() }}/pull/{{ commit.remote.pr_number }}) \
     {%- endif %}
 {%- endfor -%}
 
diff --git a/git-cliff-core/Cargo.toml b/git-cliff-core/Cargo.toml
index 1eee1e7..aa62238 100644
--- a/git-cliff-core/Cargo.toml
+++ b/git-cliff-core/Cargo.toml
@@ -97,7 +97,7 @@ version = "8.5.0"
 features = ["debug-embed", "compression"]
 
 [dev-dependencies]
-pretty_assertions = "1.4.0"
+pretty_assertions = "1.4.1"
 expect-test = "1.5.0"
 temp-dir = "0.1.13"
 
diff --git a/git-cliff-core/src/changelog.rs b/git-cliff-core/src/changelog.rs
index 06b77a2..7cf3115 100644
--- a/git-cliff-core/src/changelog.rs
+++ b/git-cliff-core/src/changelog.rs
@@ -55,20 +55,16 @@ impl<'a> Changelog<'a> {
 		Ok(Self {
 			releases,
 			header_template: match &config.changelog.header {
-				Some(header) => Some(Template::new(header.to_string(), trim)?),
+				Some(header) => {
+					Some(Template::new("header", header.to_string(), trim)?)
+				}
 				None => None,
 			},
-			body_template: Template::new(
-				config
-					.changelog
-					.body
-					.as_deref()
-					.unwrap_or_default()
-					.to_string(),
-				trim,
-			)?,
+			body_template: get_body_template(config, trim)?,
 			footer_template: match &config.changelog.footer {
-				Some(footer) => Some(Template::new(footer.to_string(), trim)?),
+				Some(footer) => {
+					Some(Template::new("footer", footer.to_string(), trim)?)
+				}
 				None => None,
 			},
 			config,
@@ -162,21 +158,19 @@ impl<'a> Changelog<'a> {
 			.rev()
 			.filter(|release| {
 				if release.commits.is_empty() {
-					if let Some(version) = release.version.as_ref().cloned() {
+					if let Some(version) = release.version.clone() {
 						trace!("Release doesn't have any commits: {}", version);
 					}
 					false
 				} else if let Some(version) = &release.version {
-					!skip_regex
-						.map(|r| {
-							let skip_tag = r.is_match(version);
-							if skip_tag {
-								skipped_tags.push(version.clone());
-								trace!("Skipping release: {}", version)
-							}
-							skip_tag
-						})
-						.unwrap_or_default()
+					!skip_regex.is_some_and(|r| {
+						let skip_tag = r.is_match(version);
+						if skip_tag {
+							skipped_tags.push(version.clone());
+							trace!("Skipping release: {}", version);
+						}
+						skip_tag
+					})
 				} else {
 					true
 				}
@@ -475,7 +469,8 @@ impl<'a> Changelog<'a> {
 			} else {
 				(vec![], vec![])
 			};
-		for release in self.releases.iter_mut() {
+		#[cfg(feature = "remote")]
+		for release in &mut self.releases {
 			#[cfg(feature = "github")]
 			release.update_github_metadata(
 				github_commits.clone(),
@@ -612,6 +607,29 @@ impl<'a> Changelog<'a> {
 	}
 }
 
+fn get_body_template(config: &Config, trim: bool) -> Result<Template> {
+	let template_str = config
+		.changelog
+		.body
+		.as_deref()
+		.unwrap_or_default()
+		.to_string();
+	let template = Template::new("body", template_str, trim)?;
+	let deprecated_vars = [
+		"commit.github",
+		"commit.gitea",
+		"commit.gitlab",
+		"commit.bitbucket",
+	];
+	if template.contains_variable(&deprecated_vars) {
+		warn!(
+			"Variables {deprecated_vars:?} are deprecated and will be removed in \
+			 the future. Use `commit.remote` instead."
+		);
+	}
+	Ok(template)
+}
+
 #[cfg(test)]
 mod test {
 	use super::*;
@@ -805,6 +823,7 @@ mod test {
 				skip_tags:                Regex::new("v3.*").ok(),
 				ignore_tags:              None,
 				count_tags:               None,
+				use_branch_tags:          Some(false),
 				topo_order:               Some(false),
 				sort_commits:             Some(String::from("oldest")),
 				link_parsers:             None,
@@ -1081,7 +1100,7 @@ mod test {
 
 		if let Some(parsers) = config.git.commit_parsers.as_mut() {
 			for parser in parsers.iter_mut().filter(|p| p.footer.is_some()) {
-				parser.skip = Some(true)
+				parser.skip = Some(true);
 			}
 		}
 
diff --git a/git-cliff-core/src/commit.rs b/git-cliff-core/src/commit.rs
index a6005cf..c5414fc 100644
--- a/git-cliff-core/src/commit.rs
+++ b/git-cliff-core/src/commit.rs
@@ -125,18 +125,24 @@ pub struct Commit<'a> {
 	pub merge_commit:  bool,
 	/// Arbitrary data to be used with the `--from-context` CLI option.
 	pub extra:         Option<Value>,
+	/// Remote metadata of the commit.
+	pub remote:        Option<crate::contributor::RemoteContributor>,
 	/// GitHub metadata of the commit.
 	#[cfg(feature = "github")]
-	pub github:        crate::remote::RemoteContributor,
+	#[deprecated(note = "Use `remote` field instead")]
+	pub github:        crate::contributor::RemoteContributor,
 	/// GitLab metadata of the commit.
 	#[cfg(feature = "gitlab")]
-	pub gitlab:        crate::remote::RemoteContributor,
+	#[deprecated(note = "Use `remote` field instead")]
+	pub gitlab:        crate::contributor::RemoteContributor,
 	/// Gitea metadata of the commit.
 	#[cfg(feature = "gitea")]
-	pub gitea:         crate::remote::RemoteContributor,
+	#[deprecated(note = "Use `remote` field instead")]
+	pub gitea:         crate::contributor::RemoteContributor,
 	/// Bitbucket metadata of the commit.
 	#[cfg(feature = "bitbucket")]
-	pub bitbucket:     crate::remote::RemoteContributor,
+	#[deprecated(note = "Use `remote` field instead")]
+	pub bitbucket:     crate::contributor::RemoteContributor,
 }
 
 impl<'a> From<String> for Commit<'a> {
@@ -166,7 +172,7 @@ impl<'a> From<&GitCommit<'a>> for Commit<'a> {
 	fn from(commit: &GitCommit<'a>) -> Self {
 		Commit {
 			id: commit.id().to_string(),
-			message: commit.message().unwrap_or_default().to_string(),
+			message: commit.message().unwrap_or_default().trim_end().to_string(),
 			author: commit.author().into(),
 			committer: commit.committer().into(),
 			merge_commit: commit.parent_count() > 1,
@@ -275,7 +281,7 @@ impl Commit<'_> {
 		for parser in parsers {
 			let mut regex_checks = Vec::new();
 			if let Some(message_regex) = parser.message.as_ref() {
-				regex_checks.push((message_regex, self.message.to_string()))
+				regex_checks.push((message_regex, self.message.to_string()));
 			}
 			let body = self
 				.conv
@@ -283,7 +289,7 @@ impl Commit<'_> {
 				.and_then(|v| v.body())
 				.map(|v| v.to_string());
 			if let Some(body_regex) = parser.body.as_ref() {
-				regex_checks.push((body_regex, body.clone().unwrap_or_default()))
+				regex_checks.push((body_regex, body.clone().unwrap_or_default()));
 			}
 			if let (Some(footer_regex), Some(footers)) = (
 				parser.footer.as_ref(),
@@ -341,11 +347,9 @@ impl Commit<'_> {
 							}
 							value
 						};
-						self.group =
-							parser.group.as_ref().cloned().map(regex_replace);
-						self.scope =
-							parser.scope.as_ref().cloned().map(regex_replace);
-						self.default_scope = parser.default_scope.as_ref().cloned();
+						self.group = parser.group.clone().map(regex_replace);
+						self.scope = parser.scope.clone().map(regex_replace);
+						self.default_scope = parser.default_scope.clone();
 						return Ok(self);
 					}
 				}
@@ -398,6 +402,7 @@ impl Commit<'_> {
 }
 
 impl Serialize for Commit<'_> {
+	#[allow(deprecated)]
 	fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
 	where
 		S: Serializer,
@@ -466,6 +471,9 @@ impl Serialize for Commit<'_> {
 		commit.serialize_field("gitea", &self.gitea)?;
 		#[cfg(feature = "bitbucket")]
 		commit.serialize_field("bitbucket", &self.bitbucket)?;
+		if let Some(remote) = &self.remote {
+			commit.serialize_field("remote", remote)?;
+		}
 		commit.end()
 	}
 }
@@ -489,7 +497,7 @@ mod test {
 			),
 		];
 		for (commit, is_conventional) in &test_cases {
-			assert_eq!(is_conventional, &commit.clone().into_conventional().is_ok())
+			assert_eq!(is_conventional, &commit.clone().into_conventional().is_ok());
 		}
 		let commit = test_cases[0].0.clone().parse(
 			&[CommitParser {
@@ -585,7 +593,7 @@ mod test {
 			),
 		];
 		for (commit, is_conventional) in &test_cases {
-			assert_eq!(is_conventional, &commit.clone().into_conventional().is_ok())
+			assert_eq!(is_conventional, &commit.clone().into_conventional().is_ok());
 		}
 		let commit = Commit::new(
 			String::from("123123"),
diff --git a/git-cliff-core/src/config.rs b/git-cliff-core/src/config.rs
index 5949d33..a39af6a 100644
--- a/git-cliff-core/src/config.rs
+++ b/git-cliff-core/src/config.rs
@@ -115,6 +115,8 @@ pub struct GitConfig {
 	/// Regex to count matched tags.
 	#[serde(with = "serde_regex", default)]
 	pub count_tags:               Option<Regex>,
+	/// Include only the tags that belong to the current branch.
+	pub use_branch_tags:          Option<bool>,
 	/// Whether to sort tags topologically.
 	pub topo_order:               Option<bool>,
 	/// Sorting of the commits inside sections.
@@ -349,7 +351,7 @@ impl Config {
 	/// Reads the config file contents from project manifest (e.g. Cargo.toml,
 	/// pyproject.toml)
 	pub fn read_from_manifest() -> Result<Option<String>> {
-		for info in (*MANIFEST_INFO).iter() {
+		for info in &(*MANIFEST_INFO) {
 			if info.path.exists() {
 				let contents = fs::read_to_string(&info.path)?;
 				if info.regex.is_match(&contents) {
diff --git a/git-cliff-core/src/contributor.rs b/git-cliff-core/src/contributor.rs
new file mode 100644
index 00000000..957ce4a
--- /dev/null
+++ b/git-cliff-core/src/contributor.rs
@@ -0,0 +1,29 @@
+use serde::{
+	Deserialize,
+	Serialize,
+};
+use std::hash::{
+	Hash,
+	Hasher,
+};
+
+/// Representation of a remote contributor.
+#[derive(Debug, Default, Clone, Eq, PartialEq, Deserialize, Serialize)]
+pub struct RemoteContributor {
+	/// Username.
+	pub username:      Option<String>,
+	/// Title of the pull request.
+	pub pr_title:      Option<String>,
+	/// The pull request that the user created.
+	pub pr_number:     Option<i64>,
+	/// Labels of the pull request.
+	pub pr_labels:     Vec<String>,
+	/// Whether if the user contributed for the first time.
+	pub is_first_time: bool,
+}
+
+impl Hash for RemoteContributor {
+	fn hash<H: Hasher>(&self, state: &mut H) {
+		self.username.hash(state);
+	}
+}
diff --git a/git-cliff-core/src/embed.rs b/git-cliff-core/src/embed.rs
index 0cf2d29..79450df 100644
--- a/git-cliff-core/src/embed.rs
+++ b/git-cliff-core/src/embed.rs
@@ -4,6 +4,7 @@ use crate::error::{
 	Result,
 };
 use rust_embed::RustEmbed;
+use std::path::Path;
 use std::str;
 
 /// Default configuration file embedder/extractor.
@@ -44,7 +45,10 @@ pub struct BuiltinConfig;
 impl BuiltinConfig {
 	/// Extracts the embedded content.
 	pub fn get_config(mut name: String) -> Result<String> {
-		if !name.ends_with(".toml") {
+		if !Path::new(&name)
+			.extension()
+			.map_or(false, |ext| ext.eq_ignore_ascii_case("toml"))
+		{
 			name = format!("{name}.toml");
 		}
 		let contents = match Self::get(&name) {
diff --git a/git-cliff-core/src/lib.rs b/git-cliff-core/src/lib.rs
index 812e0e7..1851ca9 100644
--- a/git-cliff-core/src/lib.rs
+++ b/git-cliff-core/src/lib.rs
@@ -20,6 +20,8 @@ pub mod command;
 pub mod commit;
 /// Config file parser.
 pub mod config;
+/// Remote contributor.
+pub mod contributor;
 /// Embedded file handler.
 pub mod embed;
 /// Error handling.
diff --git a/git-cliff-core/src/release.rs b/git-cliff-core/src/release.rs
index 3c9fcab..3e4dd6f 100644
--- a/git-cliff-core/src/release.rs
+++ b/git-cliff-core/src/release.rs
@@ -1,16 +1,18 @@
 use crate::error::Result;
-#[cfg(feature = "remote")]
-use crate::remote::{
-	RemoteCommit,
-	RemoteContributor,
-	RemotePullRequest,
-	RemoteReleaseMetadata,
-};
 use crate::{
 	commit::Commit,
 	config::Bump,
 	config::BumpType,
 };
+#[cfg(feature = "remote")]
+use crate::{
+	contributor::RemoteContributor,
+	remote::{
+		RemoteCommit,
+		RemotePullRequest,
+		RemoteReleaseMetadata,
+	},
+};
 
 use next_version::{
 	NextVersion,
@@ -179,6 +181,7 @@ impl<'a> Releases<'a> {
 #[cfg(test)]
 mod test {
 	use super::*;
+	use pretty_assertions::assert_eq;
 	#[test]
 	fn bump_version() -> Result<()> {
 		fn build_release<'a>(version: &str, commits: &'a [&str]) -> Release<'a> {
@@ -539,6 +542,7 @@ mod test {
 			.map(|v| Box::new(v) as Box<dyn RemotePullRequest>)
 			.collect(),
 		)?;
+		#[allow(deprecated)]
 		let expected_commits = vec![
 			Commit {
 				id: String::from("1d244937ee6ceb8e0314a4a201ba93a7a61f2071"),
@@ -550,6 +554,13 @@ mod test {
 					pr_labels:     vec![String::from("rust")],
 					is_first_time: false,
 				},
+				remote: Some(RemoteContributor {
+					username:      Some(String::from("orhun")),
+					pr_title:      Some(String::from("1")),
+					pr_number:     Some(42),
+					pr_labels:     vec![String::from("rust")],
+					is_first_time: false,
+				}),
 				..Default::default()
 			},
 			Commit {
@@ -562,6 +573,13 @@ mod test {
 					pr_labels:     vec![String::from("rust")],
 					is_first_time: false,
 				},
+				remote: Some(RemoteContributor {
+					username:      Some(String::from("orhun")),
+					pr_title:      Some(String::from("2")),
+					pr_number:     Some(66),
+					pr_labels:     vec![String::from("rust")],
+					is_first_time: false,
+				}),
 				..Default::default()
 			},
 			Commit {
@@ -574,6 +592,13 @@ mod test {
 					pr_labels:     vec![String::from("deps")],
 					is_first_time: false,
 				},
+				remote: Some(RemoteContributor {
+					username:      Some(String::from("nuhro")),
+					pr_title:      Some(String::from("3")),
+					pr_number:     Some(53),
+					pr_labels:     vec![String::from("deps")],
+					is_first_time: false,
+				}),
 				..Default::default()
 			},
 			Commit {
@@ -586,6 +611,13 @@ mod test {
 					pr_labels:     vec![String::from("deps")],
 					is_first_time: false,
 				},
+				remote: Some(RemoteContributor {
+					username:      Some(String::from("awesome_contributor")),
+					pr_title:      Some(String::from("4")),
+					pr_number:     Some(1000),
+					pr_labels:     vec![String::from("deps")],
+					is_first_time: false,
+				}),
 				..Default::default()
 			},
 			Commit {
@@ -598,6 +630,13 @@ mod test {
 					pr_labels:     vec![String::from("github")],
 					is_first_time: false,
 				},
+				remote: Some(RemoteContributor {
+					username:      Some(String::from("orhun")),
+					pr_title:      Some(String::from("5")),
+					pr_number:     Some(999999),
+					pr_labels:     vec![String::from("github")],
+					is_first_time: false,
+				}),
 				..Default::default()
 			},
 			Commit {
@@ -610,6 +649,13 @@ mod test {
 					pr_labels:     vec![],
 					is_first_time: false,
 				},
+				remote: Some(RemoteContributor {
+					username:      Some(String::from("someone")),
+					pr_title:      None,
+					pr_number:     None,
+					pr_labels:     vec![],
+					is_first_time: false,
+				}),
 				..Default::default()
 			},
 		];
@@ -703,6 +749,7 @@ mod test {
 			github: RemoteReleaseMetadata {
 				contributors: vec![],
 			},
+			#[cfg(feature = "gitlab")]
 			gitlab: RemoteReleaseMetadata {
 				contributors: vec![],
 			},
@@ -884,6 +931,7 @@ mod test {
 				labels:            vec![String::from("rust")],
 			})],
 		)?;
+		#[allow(deprecated)]
 		let expected_commits = vec![
 			Commit {
 				id: String::from("1d244937ee6ceb8e0314a4a201ba93a7a61f2071"),
@@ -895,6 +943,13 @@ mod test {
 					pr_labels:     vec![String::from("rust")],
 					is_first_time: false,
 				},
+				remote: Some(RemoteContributor {
+					username:      Some(String::from("orhun")),
+					pr_title:      Some(String::from("1")),
+					pr_number:     Some(1),
+					pr_labels:     vec![String::from("rust")],
+					is_first_time: false,
+				}),
 				..Default::default()
 			},
 			Commit {
@@ -907,6 +962,13 @@ mod test {
 					pr_labels:     vec![],
 					is_first_time: false,
 				},
+				remote: Some(RemoteContributor {
+					username:      Some(String::from("orhun")),
+					pr_title:      None,
+					pr_number:     None,
+					pr_labels:     vec![],
+					is_first_time: false,
+				}),
 				..Default::default()
 			},
 			Commit {
@@ -919,6 +981,13 @@ mod test {
 					pr_labels:     vec![],
 					is_first_time: false,
 				},
+				remote: Some(RemoteContributor {
+					username:      Some(String::from("nuhro")),
+					pr_title:      None,
+					pr_number:     None,
+					pr_labels:     vec![],
+					is_first_time: false,
+				}),
 				..Default::default()
 			},
 			Commit {
@@ -931,6 +1000,13 @@ mod test {
 					pr_labels:     vec![],
 					is_first_time: false,
 				},
+				remote: Some(RemoteContributor {
+					username:      Some(String::from("awesome_contributor")),
+					pr_title:      None,
+					pr_number:     None,
+					pr_labels:     vec![],
+					is_first_time: false,
+				}),
 				..Default::default()
 			},
 			Commit {
@@ -943,6 +1019,13 @@ mod test {
 					pr_labels:     vec![],
 					is_first_time: false,
 				},
+				remote: Some(RemoteContributor {
+					username:      Some(String::from("orhun")),
+					pr_title:      None,
+					pr_number:     None,
+					pr_labels:     vec![],
+					is_first_time: false,
+				}),
 				..Default::default()
 			},
 			Commit {
@@ -955,6 +1038,13 @@ mod test {
 					pr_labels:     vec![],
 					is_first_time: false,
 				},
+				remote: Some(RemoteContributor {
+					username:      Some(String::from("someone")),
+					pr_title:      None,
+					pr_number:     None,
+					pr_labels:     vec![],
+					is_first_time: false,
+				}),
 				..Default::default()
 			},
 		];
@@ -1053,6 +1143,7 @@ mod test {
 			gitlab: RemoteReleaseMetadata {
 				contributors: vec![],
 			},
+			#[cfg(feature = "gitea")]
 			gitea: RemoteReleaseMetadata {
 				contributors: vec![],
 			},
@@ -1173,6 +1264,7 @@ mod test {
 			.map(|v| Box::new(v) as Box<dyn RemotePullRequest>)
 			.collect(),
 		)?;
+		#[allow(deprecated)]
 		let expected_commits = vec![
 			Commit {
 				id: String::from("1d244937ee6ceb8e0314a4a201ba93a7a61f2071"),
@@ -1184,6 +1276,13 @@ mod test {
 					pr_labels:     vec![String::from("rust")],
 					is_first_time: false,
 				},
+				remote: Some(RemoteContributor {
+					username:      Some(String::from("orhun")),
+					pr_title:      Some(String::from("1")),
+					pr_number:     Some(42),
+					pr_labels:     vec![String::from("rust")],
+					is_first_time: false,
+				}),
 				..Default::default()
 			},
 			Commit {
@@ -1196,6 +1295,13 @@ mod test {
 					pr_labels:     vec![String::from("rust")],
 					is_first_time: false,
 				},
+				remote: Some(RemoteContributor {
+					username:      Some(String::from("orhun")),
+					pr_title:      Some(String::from("2")),
+					pr_number:     Some(66),
+					pr_labels:     vec![String::from("rust")],
+					is_first_time: false,
+				}),
 				..Default::default()
 			},
 			Commit {
@@ -1208,6 +1314,13 @@ mod test {
 					pr_labels:     vec![String::from("deps")],
 					is_first_time: false,
 				},
+				remote: Some(RemoteContributor {
+					username:      Some(String::from("nuhro")),
+					pr_title:      Some(String::from("3")),
+					pr_number:     Some(53),
+					pr_labels:     vec![String::from("deps")],
+					is_first_time: false,
+				}),
 				..Default::default()
 			},
 			Commit {
@@ -1220,6 +1333,13 @@ mod test {
 					pr_labels:     vec![String::from("deps")],
 					is_first_time: false,
 				},
+				remote: Some(RemoteContributor {
+					username:      Some(String::from("awesome_contributor")),
+					pr_title:      Some(String::from("4")),
+					pr_number:     Some(1000),
+					pr_labels:     vec![String::from("deps")],
+					is_first_time: false,
+				}),
 				..Default::default()
 			},
 			Commit {
@@ -1232,6 +1352,13 @@ mod test {
 					pr_labels:     vec![String::from("github")],
 					is_first_time: false,
 				},
+				remote: Some(RemoteContributor {
+					username:      Some(String::from("orhun")),
+					pr_title:      Some(String::from("5")),
+					pr_number:     Some(999999),
+					pr_labels:     vec![String::from("github")],
+					is_first_time: false,
+				}),
 				..Default::default()
 			},
 			Commit {
@@ -1244,6 +1371,13 @@ mod test {
 					pr_labels:     vec![],
 					is_first_time: false,
 				},
+				remote: Some(RemoteContributor {
+					username:      Some(String::from("someone")),
+					pr_title:      None,
+					pr_number:     None,
+					pr_labels:     vec![],
+					is_first_time: false,
+				}),
 				..Default::default()
 			},
 		];
diff --git a/git-cliff-core/src/remote/bitbucket.rs b/git-cliff-core/src/remote/bitbucket.rs
index 7597711..f45a47c 100644
--- a/git-cliff-core/src/remote/bitbucket.rs
+++ b/git-cliff-core/src/remote/bitbucket.rs
@@ -22,7 +22,8 @@ pub const START_FETCHING_MSG: &str = "Retrieving data from Bitbucket...";
 pub const FINISHED_FETCHING_MSG: &str = "Done fetching Bitbucket data.";
 
 /// Template variables related to this remote.
-pub(crate) const TEMPLATE_VARIABLES: &[&str] = &["bitbucket", "commit.bitbucket"];
+pub(crate) const TEMPLATE_VARIABLES: &[&str] =
+	&["bitbucket", "commit.bitbucket", "commit.remote"];
 
 /// Maximum number of entries to fetch for bitbucket pull requests.
 pub(crate) const BITBUCKET_MAX_PAGE_PRS: usize = 50;
diff --git a/git-cliff-core/src/remote/gitea.rs b/git-cliff-core/src/remote/gitea.rs
index 251776c..f6df6b2 100644
--- a/git-cliff-core/src/remote/gitea.rs
+++ b/git-cliff-core/src/remote/gitea.rs
@@ -22,7 +22,8 @@ pub const START_FETCHING_MSG: &str = "Retrieving data from Gitea...";
 pub const FINISHED_FETCHING_MSG: &str = "Done fetching Gitea data.";
 
 /// Template variables related to this remote.
-pub(crate) const TEMPLATE_VARIABLES: &[&str] = &["gitea", "commit.gitea"];
+pub(crate) const TEMPLATE_VARIABLES: &[&str] =
+	&["gitea", "commit.gitea", "commit.remote"];
 
 /// Representation of a single commit.
 #[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
diff --git a/git-cliff-core/src/remote/github.rs b/git-cliff-core/src/remote/github.rs
index 91e5395..8a06a70 100644
--- a/git-cliff-core/src/remote/github.rs
+++ b/git-cliff-core/src/remote/github.rs
@@ -22,7 +22,8 @@ pub const START_FETCHING_MSG: &str = "Retrieving data from GitHub...";
 pub const FINISHED_FETCHING_MSG: &str = "Done fetching GitHub data.";
 
 /// Template variables related to this remote.
-pub(crate) const TEMPLATE_VARIABLES: &[&str] = &["github", "commit.github"];
+pub(crate) const TEMPLATE_VARIABLES: &[&str] =
+	&["github", "commit.github", "commit.remote"];
 
 /// Representation of a single commit.
 #[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
diff --git a/git-cliff-core/src/remote/gitlab.rs b/git-cliff-core/src/remote/gitlab.rs
index 5863013..facf311 100644
--- a/git-cliff-core/src/remote/gitlab.rs
+++ b/git-cliff-core/src/remote/gitlab.rs
@@ -22,7 +22,8 @@ pub const START_FETCHING_MSG: &str = "Retrieving data from GitLab...";
 pub const FINISHED_FETCHING_MSG: &str = "Done fetching GitLab data.";
 
 /// Template variables related to this remote.
-pub(crate) const TEMPLATE_VARIABLES: &[&str] = &["gitlab", "commit.gitlab"];
+pub(crate) const TEMPLATE_VARIABLES: &[&str] =
+	&["gitlab", "commit.gitlab", "commit.remote"];
 
 /// Representation of a single GitLab Project.
 ///
@@ -301,6 +302,6 @@ mod test {
 		assert_eq!(
 			"https://gitlab.test.com/api/v4/projects/abc%2Fdef%2Fxyz1",
 			GitLabProject::url(1, "https://gitlab.test.com/api/v4", &remote, 0)
-		)
+		);
 	}
 }
diff --git a/git-cliff-core/src/remote/mod.rs b/git-cliff-core/src/remote/mod.rs
index 626e1d2..77d14e7 100644
--- a/git-cliff-core/src/remote/mod.rs
+++ b/git-cliff-core/src/remote/mod.rs
@@ -15,6 +15,7 @@ pub mod bitbucket;
 pub mod gitea;
 
 use crate::config::Remote;
+use crate::contributor::RemoteContributor;
 use crate::error::{
 	Error,
 	Result,
@@ -48,10 +49,7 @@ use serde::{
 	Serialize,
 };
 use std::fmt::Debug;
-use std::hash::{
-	Hash,
-	Hasher,
-};
+use std::hash::Hash;
 use std::time::Duration;
 
 /// User agent for interacting with the GitHub API.
@@ -114,27 +112,6 @@ pub struct RemoteReleaseMetadata {
 	pub contributors: Vec<RemoteContributor>,
 }
 
-/// Representation of a remote contributor.
-#[derive(Debug, Default, Clone, Eq, PartialEq, Deserialize, Serialize)]
-pub struct RemoteContributor {
-	/// Username.
-	pub username:      Option<String>,
-	/// Title of the pull request.
-	pub pr_title:      Option<String>,
-	/// The pull request that the user created.
-	pub pr_number:     Option<i64>,
-	/// Labels of the pull request.
-	pub pr_labels:     Vec<String>,
-	/// Whether if the user contributed for the first time.
-	pub is_first_time: bool,
-}
-
-impl Hash for RemoteContributor {
-	fn hash<H: Hasher>(&self, state: &mut H) {
-		self.username.hash(state);
-	}
-}
-
 /// Creates a HTTP client for the remote.
 fn create_remote_client(
 	remote: &Remote,
@@ -316,6 +293,7 @@ macro_rules! update_release_metadata {
 			///   username.
 			/// - Pull requests: needed for generating the contributor list for the
 			///   release.
+			#[allow(deprecated)]
 			pub fn $fn(
 				&mut self,
 				mut commits: Vec<Box<dyn RemoteCommit>>,
@@ -350,6 +328,7 @@ macro_rules! update_release_metadata {
 								is_first_time: false,
 							});
 						}
+						commit.remote = Some(commit.$remote.clone());
 						false
 					} else {
 						true
diff --git a/git-cliff-core/src/repo.rs b/git-cliff-core/src/repo.rs
index 5696209..0517f34 100644
--- a/git-cliff-core/src/repo.rs
+++ b/git-cliff-core/src/repo.rs
@@ -110,7 +110,7 @@ impl Repository {
 	/// directory.
 	fn normalize_pattern(pattern: Pattern) -> Pattern {
 		let star_added = match pattern.as_str().chars().last() {
-			Some('/') | Some('\\') => Pattern::new(&format!("{pattern}**"))
+			Some('/' | '\\') => Pattern::new(&format!("{pattern}**"))
 				.expect("failed to add '**' to the end of glob"),
 			_ => pattern,
 		};
@@ -310,6 +310,23 @@ impl Repository {
 		None
 	}
 
+	/// Decide whether to include tag
+	///
+	/// `head_commit` is the `latest` commit to generate changelog. It can be a
+	/// branch head or a detached head. `tag_commit` is a tagged commit. If the
+	/// commit is in the descendant graph of the head_commit or is the
+	/// head_commit itself, Changelog should include the tag.
+	fn should_include_tag(
+		&self,
+		head_commit: &Commit,
+		tag_commit: &Commit,
+	) -> Result<bool> {
+		Ok(self
+			.inner
+			.graph_descendant_of(head_commit.id(), tag_commit.id())? ||
+			head_commit.id() == tag_commit.id())
+	}
+
 	/// Parses and returns a commit-tag map.
 	///
 	/// It collects lightweight and annotated tags.
@@ -317,9 +334,11 @@ impl Repository {
 		&self,
 		pattern: &Option<Regex>,
 		topo_order: bool,
+		use_branch_tags: bool,
 	) -> Result<IndexMap<String, Tag>> {
 		let mut tags: Vec<(Commit, Tag)> = Vec::new();
 		let tag_names = self.inner.tag_names(None)?;
+		let head_commit = self.inner.head()?.peel_to_commit()?;
 		for name in tag_names
 			.iter()
 			.flatten()
@@ -330,6 +349,12 @@ impl Repository {
 		{
 			let obj = self.inner.revparse_single(&name)?;
 			if let Ok(commit) = obj.clone().into_commit() {
+				if use_branch_tags &&
+					!self.should_include_tag(&head_commit, &commit)?
+				{
+					continue;
+				}
+
 				tags.push((commit, Tag {
 					name,
 					message: None,
@@ -340,6 +365,11 @@ impl Repository {
 					.ok()
 					.and_then(|target| target.into_commit().ok())
 				{
+					if use_branch_tags &&
+						!self.should_include_tag(&head_commit, &commit)?
+					{
+						continue;
+					}
 					tags.push((commit, Tag {
 						name:    tag.name().map(String::from).unwrap_or(name),
 						message: tag.message().map(|msg| {
@@ -468,7 +498,7 @@ mod test {
 	#[test]
 	fn get_latest_tag() -> Result<()> {
 		let repository = get_repository()?;
-		let tags = repository.tags(&None, false)?;
+		let tags = repository.tags(&None, false, false)?;
 		assert_eq!(get_last_tag()?, tags.last().expect("no tags found").1.name);
 		Ok(())
 	}
@@ -476,7 +506,7 @@ mod test {
 	#[test]
 	fn git_tags() -> Result<()> {
 		let repository = get_repository()?;
-		let tags = repository.tags(&None, true)?;
+		let tags = repository.tags(&None, true, false)?;
 		assert_eq!(
 			tags.get("2b8b4d3535f29231e05c3572e919634b9af907b6")
 				.expect(
@@ -500,6 +530,7 @@ mod test {
 					.expect("the regex is not valid"),
 			),
 			true,
+			false,
 		)?;
 		assert_eq!(
 			tags.get("2b8b4d3535f29231e05c3572e919634b9af907b6")
diff --git a/git-cliff-core/src/template.rs b/git-cliff-core/src/template.rs
index f8c724d..4cbe496 100644
--- a/git-cliff-core/src/template.rs
+++ b/git-cliff-core/src/template.rs
@@ -22,6 +22,9 @@ use tera::{
 /// Wrapper for [`Tera`].
 #[derive(Debug)]
 pub struct Template {
+	/// Template name.
+	name:          String,
+	/// Internal Tera instance.
 	tera:          Tera,
 	/// Template variables.
 	#[cfg_attr(not(feature = "github"), allow(dead_code))]
@@ -30,16 +33,16 @@ pub struct Template {
 
 impl Template {
 	/// Constructs a new instance.
-	pub fn new(mut template: String, trim: bool) -> Result<Self> {
+	pub fn new(name: &str, mut content: String, trim: bool) -> Result<Self> {
 		if trim {
-			template = template
+			content = content
 				.lines()
 				.map(|v| v.trim())
 				.collect::<Vec<&str>>()
-				.join("\n")
+				.join("\n");
 		}
 		let mut tera = Tera::default();
-		if let Err(e) = tera.add_raw_template("template", &template) {
+		if let Err(e) = tera.add_raw_template(name, &content) {
 			return if let Some(error_source) = e.source() {
 				Err(Error::TemplateParseError(error_source.to_string()))
 			} else {
@@ -48,7 +51,8 @@ impl Template {
 		}
 		tera.register_filter("upper_first", Self::upper_first_filter);
 		Ok(Self {
-			variables: Self::get_template_variables(&tera)?,
+			name: name.to_string(),
+			variables: Self::get_template_variables(name, &tera)?,
 			tera,
 		})
 	}
@@ -129,18 +133,17 @@ impl Template {
 	}
 
 	/// Returns the variable names that are used in the template.
-	fn get_template_variables(tera: &Tera) -> Result<Vec<String>> {
+	fn get_template_variables(name: &str, tera: &Tera) -> Result<Vec<String>> {
 		let mut variables = HashSet::new();
-		let ast = &tera.get_template("template")?.ast;
+		let ast = &tera.get_template(name)?.ast;
 		for node in ast {
 			Self::find_identifiers(node, &mut variables);
 		}
-		trace!("Template variables: {variables:?}");
+		trace!("Template variables for {name}: {variables:?}");
 		Ok(variables.into_iter().collect())
 	}
 
 	/// Returns `true` if the template contains one of the given variables.
-	#[cfg(feature = "remote")]
 	pub(crate) fn contains_variable(&self, variables: &[&str]) -> bool {
 		variables
 			.iter()
@@ -160,7 +163,7 @@ impl Template {
 				context.insert(key.clone(), &value);
 			}
 		}
-		match self.tera.render("template", &context) {
+		match self.tera.render(&self.name, &context) {
 			Ok(mut v) => {
 				for postprocessor in postprocessors {
 					postprocessor.replace(&mut v, vec![])?;
@@ -243,7 +246,7 @@ mod test {
 		### {{ commit.group }}
 		- {{ commit.message | upper_first }}
 		{% endfor %}"#;
-		let mut template = Template::new(template.to_string(), false)?;
+		let mut template = Template::new("test", template.to_string(), false)?;
 		let release = get_fake_release_data();
 		assert_eq!(
 			"\n\t\t## 1.0 - 2023\n\t\t\n\t\t### feat\n\t\t- Add xyz\n\t\t\n\t\t### \
@@ -282,7 +285,7 @@ mod test {
 		let template = r#"
 		##  {{ version }}
 		"#;
-		let template = Template::new(template.to_string(), true)?;
+		let template = Template::new("test", template.to_string(), true)?;
 		let release = get_fake_release_data();
 		assert_eq!(
 			"\n##  1.0\n",
@@ -301,7 +304,7 @@ mod test {
 		let template =
 			"{% set hello_variable = 'hello' %}{{ hello_variable | upper_first }}";
 		let release = get_fake_release_data();
-		let template = Template::new(template.to_string(), true)?;
+		let template = Template::new("test", template.to_string(), true)?;
 		let r = template.render(
 			&release,
 			Option::<HashMap<&str, String>>::None.as_ref(),
diff --git a/git-cliff/Cargo.toml b/git-cliff/Cargo.toml
index 374baf2..312700b 100644
--- a/git-cliff/Cargo.toml
+++ b/git-cliff/Cargo.toml
@@ -48,7 +48,7 @@ secrecy.workspace = true
 lazy_static.workspace = true
 dirs.workspace = true
 clap = { version = "4.5.16", features = ["derive", "env", "wrap_help", "cargo"] }
-clap_complete = "4.5.23"
+clap_complete = "4.5.28"
 clap_mangen = "0.2.23"
 shellexpand = "3.1.0"
 update-informer = { version = "1.1.0", optional = true }
@@ -63,7 +63,7 @@ version = "2.5.0" # managed by release.sh
 path = "../git-cliff-core"
 
 [dev-dependencies]
-pretty_assertions = "1.4.0"
+pretty_assertions = "1.4.1"
 
 # metadata for cargo-binstall to get the right artifacts
 [package.metadata.binstall]
diff --git a/git-cliff/src/args.rs b/git-cliff/src/args.rs
index 2be4fbd..f62904a 100644
--- a/git-cliff/src/args.rs
+++ b/git-cliff/src/args.rs
@@ -229,6 +229,9 @@ pub struct Opt {
 	/// Sorts the tags topologically.
 	#[arg(long, help_heading = Some("FLAGS"))]
 	pub topo_order:       bool,
+	/// Include only the tags that belong to the current branch.
+	#[arg(long, help_heading = Some("FLAGS"))]
+	pub use_branch_tags:  bool,
 	/// Disables the external command execution.
 	#[arg(long, help_heading = Some("FLAGS"))]
 	pub no_exec:          bool,
@@ -301,7 +304,7 @@ pub struct Opt {
 		hide = !cfg!(feature = "gitea"),
 	)]
 	pub gitea_token:      Option<SecretString>,
-	/// Sets the GitLab repository.
+	/// Sets the Gitea repository.
 	#[arg(
 		long,
 		env = "GITEA_REPO",
@@ -446,7 +449,7 @@ mod tests {
 
 	#[test]
 	fn verify_cli() {
-		Opt::command().debug_assert()
+		Opt::command().debug_assert();
 	}
 
 	#[test]
diff --git a/git-cliff/src/lib.rs b/git-cliff/src/lib.rs
index ea8dcb2..bafb9b9 100644
--- a/git-cliff/src/lib.rs
+++ b/git-cliff/src/lib.rs
@@ -83,7 +83,11 @@ fn process_repository<'a>(
 	config: &mut Config,
 	args: &Opt,
 ) -> Result<Vec<Release<'a>>> {
-	let mut tags = repository.tags(&config.git.tag_pattern, args.topo_order)?;
+	let mut tags = repository.tags(
+		&config.git.tag_pattern,
+		args.topo_order,
+		args.use_branch_tags,
+	)?;
 	let skip_regex = config.git.skip_tags.as_ref();
 	let ignore_regex = config.git.ignore_tags.as_ref();
 	let count_tags = config.git.count_tags.as_ref();
@@ -99,7 +103,7 @@ fn process_repository<'a>(
 		let count = count_tags.map_or(true, |r| {
 			let count_tag = r.is_match(name);
 			if count_tag {
-				trace!("Counting release: {}", name)
+				trace!("Counting release: {}", name);
 			}
 			count_tag
 		});
@@ -111,7 +115,7 @@ fn process_repository<'a>(
 
 			let ignore_tag = r.is_match(name);
 			if ignore_tag {
-				trace!("Ignoring release: {}", name)
+				trace!("Ignoring release: {}", name);
 			}
 			ignore_tag
 		});
@@ -235,7 +239,7 @@ fn process_repository<'a>(
 		if let Some(commit_id) = commits.first().map(|c| c.id().to_string()) {
 			match tags.get(&commit_id) {
 				Some(tag) => {
-					warn!("There is already a tag ({:?}) for {}", tag, commit_id)
+					warn!("There is already a tag ({}) for {}", tag.name, commit_id);
 				}
 				None => {
 					tags.insert(commit_id, repository.resolve_tag(tag));
@@ -298,13 +302,6 @@ fn process_repository<'a>(
 			.extend(custom_commits.iter().cloned().map(Commit::from));
 	}
 
-	// Set custom message for the latest release.
-	if let Some(message) = &args.with_tag_message {
-		if let Some(latest_release) = releases.iter_mut().last() {
-			latest_release.message = Some(message.to_owned());
-		}
-	}
-
 	// Set the previous release if the first release does not have one set.
 	if releases[0]
 		.previous
@@ -339,6 +336,17 @@ fn process_repository<'a>(
 		}
 	}
 
+	// Set custom message for the latest release.
+	if let Some(message) = &args.with_tag_message {
+		if let Some(latest_release) = releases
+			.iter_mut()
+			.filter(|release| !release.commits.is_empty())
+			.last()
+		{
+			latest_release.message = Some(message.to_owned());
+		}
+	}
+
 	Ok(releases)
 }
 
@@ -410,7 +418,7 @@ pub fn run(mut args: Opt) -> Result<()> {
 		}
 		EmbeddedConfig::parse()?
 	};
-	if config.changelog.body.is_none() && !args.context {
+	if config.changelog.body.is_none() && !args.context && !args.bumped_version {
 		warn!("Changelog body is not specified, using the default template.");
 		config.changelog.body = EmbeddedConfig::parse()?.changelog.body;
 	}
@@ -460,6 +468,13 @@ pub fn run(mut args: Opt) -> Result<()> {
 			args.topo_order = topo_order;
 		}
 	}
+
+	if !args.use_branch_tags {
+		if let Some(use_branch_tags) = config.git.use_branch_tags {
+			args.use_branch_tags = use_branch_tags;
+		}
+	}
+
 	if args.github_token.is_some() {
 		config.remote.github.token.clone_from(&args.github_token);
 	}
@@ -524,7 +539,7 @@ pub fn run(mut args: Opt) -> Result<()> {
 
 	// Process commits and releases for the changelog.
 	if let Some(BumpOption::Specific(bump_type)) = args.bump {
-		config.bump.bump_type = Some(bump_type)
+		config.bump.bump_type = Some(bump_type);
 	}
 
 	// Generate changelog from context.
@@ -564,7 +579,7 @@ pub fn run(mut args: Opt) -> Result<()> {
 						sha: Some(sha1.to_string()),
 						skip: Some(true),
 						..Default::default()
-					})
+					});
 				}
 			}
 
diff --git a/npm/git-cliff/eslint.config.js b/npm/git-cliff/eslint.config.js
new file mode 100644
index 00000000..b59b53c
--- /dev/null
+++ b/npm/git-cliff/eslint.config.js
@@ -0,0 +1,16 @@
+// @ts-check
+
+import eslint from "@eslint/js";
+import tseslint from "typescript-eslint";
+
+export default tseslint.config(
+  eslint.configs.recommended,
+  ...tseslint.configs.recommended,
+  {
+    languageOptions: {
+      parserOptions: {
+        project: "./tsconfig.eslint.json",
+      },
+    },
+  }
+);
diff --git a/npm/git-cliff/package.json b/npm/git-cliff/package.json
index ae3cff1..e438d2c 100644
--- a/npm/git-cliff/package.json
+++ b/npm/git-cliff/package.json
@@ -27,8 +27,8 @@
   ],
   "scripts": {
     "typecheck": "tsc",
-    "lint": "eslint .",
-    "lint:fix": "eslint . --fix",
+    "lint": "eslint src",
+    "lint:fix": "eslint src --fix",
     "build": "tsup",
     "dev": "yarn build && node lib/cli/cli.js"
   },
@@ -80,12 +80,15 @@
     "execa": "^8.0.1"
   },
   "devDependencies": {
-    "@types/node": "^20.11.22",
-    "@typescript-eslint/eslint-plugin": "^7.1.0",
-    "@typescript-eslint/parser": "^7.1.0",
-    "eslint": "^8.57.0",
-    "tsup": "^8.0.2",
-    "typescript": "^5.3.3"
+    "@eslint/js": "^9.10.0",
+    "@types/eslint__js": "^8.42.3",
+    "@types/node": "^20.16.5",
+    "@typescript-eslint/eslint-plugin": "^8.4.0",
+    "@typescript-eslint/parser": "^8.4.0",
+    "eslint": "^9.10.0",
+    "tsup": "^8.2.4",
+    "typescript": "^5.5.4",
+    "typescript-eslint": "^8.4.0"
   },
   "optionalDependencies": {
     "git-cliff-darwin-arm64": "2.5.0",
@@ -95,20 +98,6 @@
     "git-cliff-windows-arm64": "2.5.0",
     "git-cliff-windows-x64": "2.5.0"
   },
-  "eslintConfig": {
-    "extends": [
-      "eslint:recommended",
-      "plugin:@typescript-eslint/recommended"
-    ],
-    "parser": "@typescript-eslint/parser",
-    "plugins": [
-      "@typescript-eslint"
-    ],
-    "ignorePatterns": [
-      "lib/*"
-    ],
-    "root": true
-  },
   "packageManager": "yarn@4.1.0",
   "publishConfig": {
     "access": "public"
diff --git a/npm/git-cliff/src/options.ts b/npm/git-cliff/src/options.ts
index 6f34693..addc330 100644
--- a/npm/git-cliff/src/options.ts
+++ b/npm/git-cliff/src/options.ts
@@ -1,29 +1,92 @@
 export type Options = Partial<{
+  //#region Flags
+  /** Prints help information */
   help: boolean;
+  /** Prints version information */
   version: boolean;
+  /** Increases the logging verbosity */
   verbose: boolean;
+  /** Prints bumped version for unreleased changes */
+  bumpedVersion: boolean;
+  /** Processes the commits starting from the latest tag */
+  latest: boolean;
+  /** Processes the commits that belong to the current tag */
+  current: boolean;
+  /** Processes the commits that do not belong to a tag */
+  unreleased: boolean;
+  /** Sorts the tags topologically */
+  topoOrder: boolean;
+  /** Disables the external command execution */
+  noExec: boolean;
+  /** Prints changelog context as JSON */
+  context: boolean;
+  //#endregion
+
+  //#region Options
+  /** Writes the default configuration file to cliff.toml */
   init: boolean | string;
+  /**
+   * Bumps the version for unreleased changes
+   * @default 'auto'
+   */
+  bump: "auto" | "major" | "minor" | "patch";
+  /**
+   * Sets the configuration file
+   * @default 'cliff.toml'
+   */
   config: string;
+  /** Sets the working directory */
   workdir: string;
+  /** Sets the git repository */
   repository: string;
+  /** Sets the path to include related commits */
   includePath: string;
+  /** Sets the path to exclude related commits */
   excludePath: string;
+  /** Sets the regex for matching git tags */
+  tagPattern: string;
+  /** Sets custom commit messages to include in the changelog */
   withCommit: string;
-  skipCommit: string;
+  /** Sets custom message for the latest release */
+  withTagMessage: string;
+  /** Sets the tags to ignore in the changelog */
+  ignoreTags: string | string[];
+  /** Sets the tags to count in the changelog */
+  countTags: string | string[];
+  /** Sets commits that will be skipped in the changelog */
+  skipCommit: string | string[];
+  /** Prepends entries to the given changelog file */
   prepend: string;
+  /** Writes output to the given file */
   output: string;
+  /** Sets the tag for the latest version */
   tag: string;
-  bump: boolean;
-  bumpedVersion: boolean;
+  /** Sets the template for the changelog body */
   body: string;
-  latest: boolean;
-  current: boolean;
-  unreleased: boolean;
-  topoOrder: boolean;
-  noExec: boolean;
-  context: boolean;
+  /** Generates changelog from a JSON context */
+  fromContext: string;
+  /** Strips the given parts from the changelog */
   strip: "header" | "footer" | "all";
+  /**
+   * Sets sorting of the commits inside sections
+   * @default 'oldest'
+   */
   sort: "oldest" | "newest";
+  /** Sets the GitHub API token */
   githubToken: string;
+  /** Sets the GitHub repository */
   githubRepo: string;
+  /** Sets the GitLab API token */
+  gitlabToken: string;
+  /** Sets the GitLab repository */
+  gitlabRepo: string;
+  /** Sets the Gitea API token */
+  giteaToken: string;
+  /** Sets the Gitea repository */
+  giteaRepo: string;
+  /** Sets the Bitbucket API token */
+  bitbucketToken: string;
+  /** Sets the Bitbucket repository */
+  bitbucketRepo: string;
+  //#endregion
 }>;
diff --git a/npm/git-cliff/src/optionsToStringArgs.ts b/npm/git-cliff/src/optionsToStringArgs.ts
index d80224f..9fc0253 100644
--- a/npm/git-cliff/src/optionsToStringArgs.ts
+++ b/npm/git-cliff/src/optionsToStringArgs.ts
@@ -13,7 +13,11 @@ export function optionsToStringArgs(options: Options): string[] {
   for (const [key, value] of Object.entries(options)) {
     const hyphenCaseKey = key.replace(/([A-Z])/g, "-$1").toLowerCase();
 
-    if (value === true) {
+    if (Array.isArray(value)) {
+      for (const arrValue of value) {
+        args.push(`--${hyphenCaseKey}`, arrValue);
+      }
+    } else if (value === true) {
       args.push(`--${hyphenCaseKey}`);
     } else if (value === false || value === null) {
       continue;
diff --git a/npm/git-cliff/yarn.lock b/npm/git-cliff/yarn.lock
index 723eef2..01162d3 100644
--- a/npm/git-cliff/yarn.lock
+++ b/npm/git-cliff/yarn.lock
@@ -12,163 +12,170 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@esbuild/aix-ppc64@npm:0.19.12":
-  version: 0.19.12
-  resolution: "@esbuild/aix-ppc64@npm:0.19.12"
+"@esbuild/aix-ppc64@npm:0.23.1":
+  version: 0.23.1
+  resolution: "@esbuild/aix-ppc64@npm:0.23.1"
   conditions: os=aix & cpu=ppc64
   languageName: node
   linkType: hard
 
-"@esbuild/android-arm64@npm:0.19.12":
-  version: 0.19.12
-  resolution: "@esbuild/android-arm64@npm:0.19.12"
+"@esbuild/android-arm64@npm:0.23.1":
+  version: 0.23.1
+  resolution: "@esbuild/android-arm64@npm:0.23.1"
   conditions: os=android & cpu=arm64
   languageName: node
   linkType: hard
 
-"@esbuild/android-arm@npm:0.19.12":
-  version: 0.19.12
-  resolution: "@esbuild/android-arm@npm:0.19.12"
+"@esbuild/android-arm@npm:0.23.1":
+  version: 0.23.1
+  resolution: "@esbuild/android-arm@npm:0.23.1"
   conditions: os=android & cpu=arm
   languageName: node
   linkType: hard
 
-"@esbuild/android-x64@npm:0.19.12":
-  version: 0.19.12
-  resolution: "@esbuild/android-x64@npm:0.19.12"
+"@esbuild/android-x64@npm:0.23.1":
+  version: 0.23.1
+  resolution: "@esbuild/android-x64@npm:0.23.1"
   conditions: os=android & cpu=x64
   languageName: node
   linkType: hard
 
-"@esbuild/darwin-arm64@npm:0.19.12":
-  version: 0.19.12
-  resolution: "@esbuild/darwin-arm64@npm:0.19.12"
+"@esbuild/darwin-arm64@npm:0.23.1":
+  version: 0.23.1
+  resolution: "@esbuild/darwin-arm64@npm:0.23.1"
   conditions: os=darwin & cpu=arm64
   languageName: node
   linkType: hard
 
-"@esbuild/darwin-x64@npm:0.19.12":
-  version: 0.19.12
-  resolution: "@esbuild/darwin-x64@npm:0.19.12"
+"@esbuild/darwin-x64@npm:0.23.1":
+  version: 0.23.1
+  resolution: "@esbuild/darwin-x64@npm:0.23.1"
   conditions: os=darwin & cpu=x64
   languageName: node
   linkType: hard
 
-"@esbuild/freebsd-arm64@npm:0.19.12":
-  version: 0.19.12
-  resolution: "@esbuild/freebsd-arm64@npm:0.19.12"
+"@esbuild/freebsd-arm64@npm:0.23.1":
+  version: 0.23.1
+  resolution: "@esbuild/freebsd-arm64@npm:0.23.1"
   conditions: os=freebsd & cpu=arm64
   languageName: node
   linkType: hard
 
-"@esbuild/freebsd-x64@npm:0.19.12":
-  version: 0.19.12
-  resolution: "@esbuild/freebsd-x64@npm:0.19.12"
+"@esbuild/freebsd-x64@npm:0.23.1":
+  version: 0.23.1
+  resolution: "@esbuild/freebsd-x64@npm:0.23.1"
   conditions: os=freebsd & cpu=x64
   languageName: node
   linkType: hard
 
-"@esbuild/linux-arm64@npm:0.19.12":
-  version: 0.19.12
-  resolution: "@esbuild/linux-arm64@npm:0.19.12"
+"@esbuild/linux-arm64@npm:0.23.1":
+  version: 0.23.1
+  resolution: "@esbuild/linux-arm64@npm:0.23.1"
   conditions: os=linux & cpu=arm64
   languageName: node
   linkType: hard
 
-"@esbuild/linux-arm@npm:0.19.12":
-  version: 0.19.12
-  resolution: "@esbuild/linux-arm@npm:0.19.12"
+"@esbuild/linux-arm@npm:0.23.1":
+  version: 0.23.1
+  resolution: "@esbuild/linux-arm@npm:0.23.1"
   conditions: os=linux & cpu=arm
   languageName: node
   linkType: hard
 
-"@esbuild/linux-ia32@npm:0.19.12":
-  version: 0.19.12
-  resolution: "@esbuild/linux-ia32@npm:0.19.12"
+"@esbuild/linux-ia32@npm:0.23.1":
+  version: 0.23.1
+  resolution: "@esbuild/linux-ia32@npm:0.23.1"
   conditions: os=linux & cpu=ia32
   languageName: node
   linkType: hard
 
-"@esbuild/linux-loong64@npm:0.19.12":
-  version: 0.19.12
-  resolution: "@esbuild/linux-loong64@npm:0.19.12"
+"@esbuild/linux-loong64@npm:0.23.1":
+  version: 0.23.1
+  resolution: "@esbuild/linux-loong64@npm:0.23.1"
   conditions: os=linux & cpu=loong64
   languageName: node
   linkType: hard
 
-"@esbuild/linux-mips64el@npm:0.19.12":
-  version: 0.19.12
-  resolution: "@esbuild/linux-mips64el@npm:0.19.12"
+"@esbuild/linux-mips64el@npm:0.23.1":
+  version: 0.23.1
+  resolution: "@esbuild/linux-mips64el@npm:0.23.1"
   conditions: os=linux & cpu=mips64el
   languageName: node
   linkType: hard
 
-"@esbuild/linux-ppc64@npm:0.19.12":
-  version: 0.19.12
-  resolution: "@esbuild/linux-ppc64@npm:0.19.12"
+"@esbuild/linux-ppc64@npm:0.23.1":
+  version: 0.23.1
+  resolution: "@esbuild/linux-ppc64@npm:0.23.1"
   conditions: os=linux & cpu=ppc64
   languageName: node
   linkType: hard
 
-"@esbuild/linux-riscv64@npm:0.19.12":
-  version: 0.19.12
-  resolution: "@esbuild/linux-riscv64@npm:0.19.12"
+"@esbuild/linux-riscv64@npm:0.23.1":
+  version: 0.23.1
+  resolution: "@esbuild/linux-riscv64@npm:0.23.1"
   conditions: os=linux & cpu=riscv64
   languageName: node
   linkType: hard
 
-"@esbuild/linux-s390x@npm:0.19.12":
-  version: 0.19.12
-  resolution: "@esbuild/linux-s390x@npm:0.19.12"
+"@esbuild/linux-s390x@npm:0.23.1":
+  version: 0.23.1
+  resolution: "@esbuild/linux-s390x@npm:0.23.1"
   conditions: os=linux & cpu=s390x
   languageName: node
   linkType: hard
 
-"@esbuild/linux-x64@npm:0.19.12":
-  version: 0.19.12
-  resolution: "@esbuild/linux-x64@npm:0.19.12"
+"@esbuild/linux-x64@npm:0.23.1":
+  version: 0.23.1
+  resolution: "@esbuild/linux-x64@npm:0.23.1"
   conditions: os=linux & cpu=x64
   languageName: node
   linkType: hard
 
-"@esbuild/netbsd-x64@npm:0.19.12":
-  version: 0.19.12
-  resolution: "@esbuild/netbsd-x64@npm:0.19.12"
+"@esbuild/netbsd-x64@npm:0.23.1":
+  version: 0.23.1
+  resolution: "@esbuild/netbsd-x64@npm:0.23.1"
   conditions: os=netbsd & cpu=x64
   languageName: node
   linkType: hard
 
-"@esbuild/openbsd-x64@npm:0.19.12":
-  version: 0.19.12
-  resolution: "@esbuild/openbsd-x64@npm:0.19.12"
+"@esbuild/openbsd-arm64@npm:0.23.1":
+  version: 0.23.1
+  resolution: "@esbuild/openbsd-arm64@npm:0.23.1"
+  conditions: os=openbsd & cpu=arm64
+  languageName: node
+  linkType: hard
+
+"@esbuild/openbsd-x64@npm:0.23.1":
+  version: 0.23.1
+  resolution: "@esbuild/openbsd-x64@npm:0.23.1"
   conditions: os=openbsd & cpu=x64
   languageName: node
   linkType: hard
 
-"@esbuild/sunos-x64@npm:0.19.12":
-  version: 0.19.12
-  resolution: "@esbuild/sunos-x64@npm:0.19.12"
+"@esbuild/sunos-x64@npm:0.23.1":
+  version: 0.23.1
+  resolution: "@esbuild/sunos-x64@npm:0.23.1"
   conditions: os=sunos & cpu=x64
   languageName: node
   linkType: hard
 
-"@esbuild/win32-arm64@npm:0.19.12":
-  version: 0.19.12
-  resolution: "@esbuild/win32-arm64@npm:0.19.12"
+"@esbuild/win32-arm64@npm:0.23.1":
+  version: 0.23.1
+  resolution: "@esbuild/win32-arm64@npm:0.23.1"
   conditions: os=win32 & cpu=arm64
   languageName: node
   linkType: hard
 
-"@esbuild/win32-ia32@npm:0.19.12":
-  version: 0.19.12
-  resolution: "@esbuild/win32-ia32@npm:0.19.12"
+"@esbuild/win32-ia32@npm:0.23.1":
+  version: 0.23.1
+  resolution: "@esbuild/win32-ia32@npm:0.23.1"
   conditions: os=win32 & cpu=ia32
   languageName: node
   linkType: hard
 
-"@esbuild/win32-x64@npm:0.19.12":
-  version: 0.19.12
-  resolution: "@esbuild/win32-x64@npm:0.19.12"
+"@esbuild/win32-x64@npm:0.23.1":
+  version: 0.23.1
+  resolution: "@esbuild/win32-x64@npm:0.23.1"
   conditions: os=win32 & cpu=x64
   languageName: node
   linkType: hard
@@ -184,45 +191,61 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@eslint-community/regexpp@npm:^4.5.1, @eslint-community/regexpp@npm:^4.6.1":
-  version: 4.10.0
-  resolution: "@eslint-community/regexpp@npm:4.10.0"
-  checksum: 10c0/c5f60ef1f1ea7649fa7af0e80a5a79f64b55a8a8fa5086de4727eb4c86c652aedee407a9c143b8995d2c0b2d75c1222bec9ba5d73dbfc1f314550554f0979ef4
+"@eslint-community/regexpp@npm:^4.10.0, @eslint-community/regexpp@npm:^4.11.0":
+  version: 4.11.0
+  resolution: "@eslint-community/regexpp@npm:4.11.0"
+  checksum: 10c0/0f6328869b2741e2794da4ad80beac55cba7de2d3b44f796a60955b0586212ec75e6b0253291fd4aad2100ad471d1480d8895f2b54f1605439ba4c875e05e523
   languageName: node
   linkType: hard
 
-"@eslint/eslintrc@npm:^2.1.4":
-  version: 2.1.4
-  resolution: "@eslint/eslintrc@npm:2.1.4"
+"@eslint/config-array@npm:^0.18.0":
+  version: 0.18.0
+  resolution: "@eslint/config-array@npm:0.18.0"
+  dependencies:
+    "@eslint/object-schema": "npm:^2.1.4"
+    debug: "npm:^4.3.1"
+    minimatch: "npm:^3.1.2"
+  checksum: 10c0/0234aeb3e6b052ad2402a647d0b4f8a6aa71524bafe1adad0b8db1dfe94d7f5f26d67c80f79bb37ac61361a1d4b14bb8fb475efe501de37263cf55eabb79868f
+  languageName: node
+  linkType: hard
+
+"@eslint/eslintrc@npm:^3.1.0":
+  version: 3.1.0
+  resolution: "@eslint/eslintrc@npm:3.1.0"
   dependencies:
     ajv: "npm:^6.12.4"
     debug: "npm:^4.3.2"
-    espree: "npm:^9.6.0"
-    globals: "npm:^13.19.0"
+    espree: "npm:^10.0.1"
+    globals: "npm:^14.0.0"
     ignore: "npm:^5.2.0"
     import-fresh: "npm:^3.2.1"
     js-yaml: "npm:^4.1.0"
     minimatch: "npm:^3.1.2"
     strip-json-comments: "npm:^3.1.1"
-  checksum: 10c0/32f67052b81768ae876c84569ffd562491ec5a5091b0c1e1ca1e0f3c24fb42f804952fdd0a137873bc64303ba368a71ba079a6f691cee25beee9722d94cc8573
+  checksum: 10c0/5b7332ed781edcfc98caa8dedbbb843abfb9bda2e86538529c843473f580e40c69eb894410eddc6702f487e9ee8f8cfa8df83213d43a8fdb549f23ce06699167
+  languageName: node
+  linkType: hard
+
+"@eslint/js@npm:9.10.0, @eslint/js@npm:^9.10.0":
+  version: 9.10.0
+  resolution: "@eslint/js@npm:9.10.0"
+  checksum: 10c0/2ac45a002dc1ccf25be46ea61001ada8d77248d1313ab4e53f3735e5ae00738a757874e41f62ad6fbd49df7dffeece66e5f53ff0d7b78a99ce4c68e8fea66753
   languageName: node
   linkType: hard
 
-"@eslint/js@npm:8.57.0":
-  version: 8.57.0
-  resolution: "@eslint/js@npm:8.57.0"
-  checksum: 10c0/9a518bb8625ba3350613903a6d8c622352ab0c6557a59fe6ff6178bf882bf57123f9d92aa826ee8ac3ee74b9c6203fe630e9ee00efb03d753962dcf65ee4bd94
+"@eslint/object-schema@npm:^2.1.4":
+  version: 2.1.4
+  resolution: "@eslint/object-schema@npm:2.1.4"
+  checksum: 10c0/e9885532ea70e483fb007bf1275968b05bb15ebaa506d98560c41a41220d33d342e19023d5f2939fed6eb59676c1bda5c847c284b4b55fce521d282004da4dda
   languageName: node
   linkType: hard
 
-"@humanwhocodes/config-array@npm:^0.11.14":
-  version: 0.11.14
-  resolution: "@humanwhocodes/config-array@npm:0.11.14"
+"@eslint/plugin-kit@npm:^0.1.0":
+  version: 0.1.0
+  resolution: "@eslint/plugin-kit@npm:0.1.0"
   dependencies:
-    "@humanwhocodes/object-schema": "npm:^2.0.2"
-    debug: "npm:^4.3.1"
-    minimatch: "npm:^3.0.5"
-  checksum: 10c0/66f725b4ee5fdd8322c737cb5013e19fac72d4d69c8bf4b7feb192fcb83442b035b92186f8e9497c220e58b2d51a080f28a73f7899bc1ab288c3be172c467541
+    levn: "npm:^0.4.1"
+  checksum: 10c0/fae97cd4efc1c32501c286abba1b5409848ce8c989e1ca6a5bb057a304a2cd721e6e957f6bc35ce95cfd0871e822ed42df3c759fecdad72c30e70802e26f83c7
   languageName: node
   linkType: hard
 
@@ -233,10 +256,10 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@humanwhocodes/object-schema@npm:^2.0.2":
-  version: 2.0.2
-  resolution: "@humanwhocodes/object-schema@npm:2.0.2"
-  checksum: 10c0/6fd83dc320231d71c4541d0244051df61f301817e9f9da9fd4cb7e44ec8aacbde5958c1665b0c419401ab935114fdf532a6ad5d4e7294b1af2f347dd91a6983f
+"@humanwhocodes/retry@npm:^0.3.0":
+  version: 0.3.0
+  resolution: "@humanwhocodes/retry@npm:0.3.0"
+  checksum: 10c0/7111ec4e098b1a428459b4e3be5a5d2a13b02905f805a2468f4fa628d072f0de2da26a27d04f65ea2846f73ba51f4204661709f05bfccff645e3cedef8781bb6
   languageName: node
   linkType: hard
 
@@ -352,254 +375,273 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@rollup/rollup-android-arm-eabi@npm:4.12.0":
-  version: 4.12.0
-  resolution: "@rollup/rollup-android-arm-eabi@npm:4.12.0"
+"@rollup/rollup-android-arm-eabi@npm:4.21.2":
+  version: 4.21.2
+  resolution: "@rollup/rollup-android-arm-eabi@npm:4.21.2"
   conditions: os=android & cpu=arm
   languageName: node
   linkType: hard
 
-"@rollup/rollup-android-arm64@npm:4.12.0":
-  version: 4.12.0
-  resolution: "@rollup/rollup-android-arm64@npm:4.12.0"
+"@rollup/rollup-android-arm64@npm:4.21.2":
+  version: 4.21.2
+  resolution: "@rollup/rollup-android-arm64@npm:4.21.2"
   conditions: os=android & cpu=arm64
   languageName: node
   linkType: hard
 
-"@rollup/rollup-darwin-arm64@npm:4.12.0":
-  version: 4.12.0
-  resolution: "@rollup/rollup-darwin-arm64@npm:4.12.0"
+"@rollup/rollup-darwin-arm64@npm:4.21.2":
+  version: 4.21.2
+  resolution: "@rollup/rollup-darwin-arm64@npm:4.21.2"
   conditions: os=darwin & cpu=arm64
   languageName: node
   linkType: hard
 
-"@rollup/rollup-darwin-x64@npm:4.12.0":
-  version: 4.12.0
-  resolution: "@rollup/rollup-darwin-x64@npm:4.12.0"
+"@rollup/rollup-darwin-x64@npm:4.21.2":
+  version: 4.21.2
+  resolution: "@rollup/rollup-darwin-x64@npm:4.21.2"
   conditions: os=darwin & cpu=x64
   languageName: node
   linkType: hard
 
-"@rollup/rollup-linux-arm-gnueabihf@npm:4.12.0":
-  version: 4.12.0
-  resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.12.0"
-  conditions: os=linux & cpu=arm
+"@rollup/rollup-linux-arm-gnueabihf@npm:4.21.2":
+  version: 4.21.2
+  resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.21.2"
+  conditions: os=linux & cpu=arm & libc=glibc
+  languageName: node
+  linkType: hard
+
+"@rollup/rollup-linux-arm-musleabihf@npm:4.21.2":
+  version: 4.21.2
+  resolution: "@rollup/rollup-linux-arm-musleabihf@npm:4.21.2"
+  conditions: os=linux & cpu=arm & libc=musl
   languageName: node
   linkType: hard
 
-"@rollup/rollup-linux-arm64-gnu@npm:4.12.0":
-  version: 4.12.0
-  resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.12.0"
+"@rollup/rollup-linux-arm64-gnu@npm:4.21.2":
+  version: 4.21.2
+  resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.21.2"
   conditions: os=linux & cpu=arm64 & libc=glibc
   languageName: node
   linkType: hard
 
-"@rollup/rollup-linux-arm64-musl@npm:4.12.0":
-  version: 4.12.0
-  resolution: "@rollup/rollup-linux-arm64-musl@npm:4.12.0"
+"@rollup/rollup-linux-arm64-musl@npm:4.21.2":
+  version: 4.21.2
+  resolution: "@rollup/rollup-linux-arm64-musl@npm:4.21.2"
   conditions: os=linux & cpu=arm64 & libc=musl
   languageName: node
   linkType: hard
 
-"@rollup/rollup-linux-riscv64-gnu@npm:4.12.0":
-  version: 4.12.0
-  resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.12.0"
+"@rollup/rollup-linux-powerpc64le-gnu@npm:4.21.2":
+  version: 4.21.2
+  resolution: "@rollup/rollup-linux-powerpc64le-gnu@npm:4.21.2"
+  conditions: os=linux & cpu=ppc64 & libc=glibc
+  languageName: node
+  linkType: hard
+
+"@rollup/rollup-linux-riscv64-gnu@npm:4.21.2":
+  version: 4.21.2
+  resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.21.2"
   conditions: os=linux & cpu=riscv64 & libc=glibc
   languageName: node
   linkType: hard
 
-"@rollup/rollup-linux-x64-gnu@npm:4.12.0":
-  version: 4.12.0
-  resolution: "@rollup/rollup-linux-x64-gnu@npm:4.12.0"
+"@rollup/rollup-linux-s390x-gnu@npm:4.21.2":
+  version: 4.21.2
+  resolution: "@rollup/rollup-linux-s390x-gnu@npm:4.21.2"
+  conditions: os=linux & cpu=s390x & libc=glibc
+  languageName: node
+  linkType: hard
+
+"@rollup/rollup-linux-x64-gnu@npm:4.21.2":
+  version: 4.21.2
+  resolution: "@rollup/rollup-linux-x64-gnu@npm:4.21.2"
   conditions: os=linux & cpu=x64 & libc=glibc
   languageName: node
   linkType: hard
 
-"@rollup/rollup-linux-x64-musl@npm:4.12.0":
-  version: 4.12.0
-  resolution: "@rollup/rollup-linux-x64-musl@npm:4.12.0"
+"@rollup/rollup-linux-x64-musl@npm:4.21.2":
+  version: 4.21.2
+  resolution: "@rollup/rollup-linux-x64-musl@npm:4.21.2"
   conditions: os=linux & cpu=x64 & libc=musl
   languageName: node
   linkType: hard
 
-"@rollup/rollup-win32-arm64-msvc@npm:4.12.0":
-  version: 4.12.0
-  resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.12.0"
+"@rollup/rollup-win32-arm64-msvc@npm:4.21.2":
+  version: 4.21.2
+  resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.21.2"
   conditions: os=win32 & cpu=arm64
   languageName: node
   linkType: hard
 
-"@rollup/rollup-win32-ia32-msvc@npm:4.12.0":
-  version: 4.12.0
-  resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.12.0"
+"@rollup/rollup-win32-ia32-msvc@npm:4.21.2":
+  version: 4.21.2
+  resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.21.2"
   conditions: os=win32 & cpu=ia32
   languageName: node
   linkType: hard
 
-"@rollup/rollup-win32-x64-msvc@npm:4.12.0":
-  version: 4.12.0
-  resolution: "@rollup/rollup-win32-x64-msvc@npm:4.12.0"
+"@rollup/rollup-win32-x64-msvc@npm:4.21.2":
+  version: 4.21.2
+  resolution: "@rollup/rollup-win32-x64-msvc@npm:4.21.2"
   conditions: os=win32 & cpu=x64
   languageName: node
   linkType: hard
 
-"@types/estree@npm:1.0.5":
+"@types/eslint@npm:*":
+  version: 9.6.1
+  resolution: "@types/eslint@npm:9.6.1"
+  dependencies:
+    "@types/estree": "npm:*"
+    "@types/json-schema": "npm:*"
+  checksum: 10c0/69ba24fee600d1e4c5abe0df086c1a4d798abf13792d8cfab912d76817fe1a894359a1518557d21237fbaf6eda93c5ab9309143dee4c59ef54336d1b3570420e
+  languageName: node
+  linkType: hard
+
+"@types/eslint__js@npm:^8.42.3":
+  version: 8.42.3
+  resolution: "@types/eslint__js@npm:8.42.3"
+  dependencies:
+    "@types/eslint": "npm:*"
+  checksum: 10c0/ccc5180b92155929a089ffb03ed62625216dcd5e46dd3197c6f82370ce8b52c7cb9df66c06b0a3017995409e023bc9eafe5a3f009e391960eacefaa1b62d9a56
+  languageName: node
+  linkType: hard
+
+"@types/estree@npm:*, @types/estree@npm:1.0.5":
   version: 1.0.5
   resolution: "@types/estree@npm:1.0.5"
   checksum: 10c0/b3b0e334288ddb407c7b3357ca67dbee75ee22db242ca7c56fe27db4e1a31989cb8af48a84dd401deb787fe10cc6b2ab1ee82dc4783be87ededbe3d53c79c70d
   languageName: node
   linkType: hard
 
-"@types/json-schema@npm:^7.0.12":
+"@types/json-schema@npm:*":
   version: 7.0.15
   resolution: "@types/json-schema@npm:7.0.15"
   checksum: 10c0/a996a745e6c5d60292f36731dd41341339d4eeed8180bb09226e5c8d23759067692b1d88e5d91d72ee83dfc00d3aca8e7bd43ea120516c17922cbcb7c3e252db
   languageName: node
   linkType: hard
 
-"@types/node@npm:^20.11.22":
-  version: 20.11.22
-  resolution: "@types/node@npm:20.11.22"
+"@types/node@npm:^20.16.5":
+  version: 20.16.5
+  resolution: "@types/node@npm:20.16.5"
   dependencies:
-    undici-types: "npm:~5.26.4"
-  checksum: 10c0/304a25607108cbc314417ba1cd0ca7061090cf9444c13f4a70c183164dc189d0e3f4cfda12619c85e5f0fc7a652e3b32501fd0e347b8425dbd5a66c3ec85c7a6
-  languageName: node
-  linkType: hard
-
-"@types/semver@npm:^7.5.0":
-  version: 7.5.8
-  resolution: "@types/semver@npm:7.5.8"
-  checksum: 10c0/8663ff927234d1c5fcc04b33062cb2b9fcfbe0f5f351ed26c4d1e1581657deebd506b41ff7fdf89e787e3d33ce05854bc01686379b89e9c49b564c4cfa988efa
+    undici-types: "npm:~6.19.2"
+  checksum: 10c0/6af7994129815010bcbc4cf8221865559c8116ff43e74a6549525c2108267596fc2d18aff5d5ecfe089fb60a119f975631343e2c65c52bfa0955ed9dc56733d6
   languageName: node
   linkType: hard
 
-"@typescript-eslint/eslint-plugin@npm:^7.1.0":
-  version: 7.1.0
-  resolution: "@typescript-eslint/eslint-plugin@npm:7.1.0"
+"@typescript-eslint/eslint-plugin@npm:8.4.0, @typescript-eslint/eslint-plugin@npm:^8.4.0":
+  version: 8.4.0
+  resolution: "@typescript-eslint/eslint-plugin@npm:8.4.0"
   dependencies:
-    "@eslint-community/regexpp": "npm:^4.5.1"
-    "@typescript-eslint/scope-manager": "npm:7.1.0"
-    "@typescript-eslint/type-utils": "npm:7.1.0"
-    "@typescript-eslint/utils": "npm:7.1.0"
-    "@typescript-eslint/visitor-keys": "npm:7.1.0"
-    debug: "npm:^4.3.4"
+    "@eslint-community/regexpp": "npm:^4.10.0"
+    "@typescript-eslint/scope-manager": "npm:8.4.0"
+    "@typescript-eslint/type-utils": "npm:8.4.0"
+    "@typescript-eslint/utils": "npm:8.4.0"
+    "@typescript-eslint/visitor-keys": "npm:8.4.0"
     graphemer: "npm:^1.4.0"
-    ignore: "npm:^5.2.4"
+    ignore: "npm:^5.3.1"
     natural-compare: "npm:^1.4.0"
-    semver: "npm:^7.5.4"
-    ts-api-utils: "npm:^1.0.1"
+    ts-api-utils: "npm:^1.3.0"
   peerDependencies:
-    "@typescript-eslint/parser": ^7.0.0
-    eslint: ^8.56.0
+    "@typescript-eslint/parser": ^8.0.0 || ^8.0.0-alpha.0
+    eslint: ^8.57.0 || ^9.0.0
   peerDependenciesMeta:
     typescript:
       optional: true
-  checksum: 10c0/e5644a987969cbb614bbf766b6bf51341e123c774953690548610147eae0041d70e48ef42be97b68a6e2f5ed9aae37fe040e8054d35bb0568c14194ba564b2d8
+  checksum: 10c0/c75e9bb176e9e0277c9f9c4c006bc2c31ac91984e555de1390a9bbe876e3b6787d59d96015b3f0cd083fd22c814aea4ed4858910d3afdd24d64ab79815da31e5
   languageName: node
   linkType: hard
 
-"@typescript-eslint/parser@npm:^7.1.0":
-  version: 7.1.0
-  resolution: "@typescript-eslint/parser@npm:7.1.0"
+"@typescript-eslint/parser@npm:8.4.0, @typescript-eslint/parser@npm:^8.4.0":
+  version: 8.4.0
+  resolution: "@typescript-eslint/parser@npm:8.4.0"
   dependencies:
-    "@typescript-eslint/scope-manager": "npm:7.1.0"
-    "@typescript-eslint/types": "npm:7.1.0"
-    "@typescript-eslint/typescript-estree": "npm:7.1.0"
-    "@typescript-eslint/visitor-keys": "npm:7.1.0"
+    "@typescript-eslint/scope-manager": "npm:8.4.0"
+    "@typescript-eslint/types": "npm:8.4.0"
+    "@typescript-eslint/typescript-estree": "npm:8.4.0"
+    "@typescript-eslint/visitor-keys": "npm:8.4.0"
     debug: "npm:^4.3.4"
   peerDependencies:
-    eslint: ^8.56.0
+    eslint: ^8.57.0 || ^9.0.0
   peerDependenciesMeta:
     typescript:
       optional: true
-  checksum: 10c0/8fcbfc8c0c86abb750173096e7ca09e1cd44aba3f6115bdb94ffb6b409b86ee23526e9d5a44935b69a6be2385893e66d8e55d92063206028dc48f70d379afcab
+  checksum: 10c0/19f3358e5bc4bbad693183eefe1a90ea64be054a934bc2c8a972ff4738b94580b55ad4955af5797db42298628caa59b3ba3f9fd960582b5fc2c836da3a4578a5
   languageName: node
   linkType: hard
 
-"@typescript-eslint/scope-manager@npm:7.1.0":
-  version: 7.1.0
-  resolution: "@typescript-eslint/scope-manager@npm:7.1.0"
+"@typescript-eslint/scope-manager@npm:8.4.0":
+  version: 8.4.0
+  resolution: "@typescript-eslint/scope-manager@npm:8.4.0"
   dependencies:
-    "@typescript-eslint/types": "npm:7.1.0"
-    "@typescript-eslint/visitor-keys": "npm:7.1.0"
-  checksum: 10c0/2fd167730bbe984343ab94739b00bd82e8cdeea9e63674b099cc5c89b420b28dbf79f40dab48022dc717db8d14ae6ee2739e0fcbdcc0321bc9da5f2602b55788
+    "@typescript-eslint/types": "npm:8.4.0"
+    "@typescript-eslint/visitor-keys": "npm:8.4.0"
+  checksum: 10c0/95188c663df7db106529c6b93c4c7c61647ed34ab6dd48114e41ddf49140ff606c5501ce2ae451a988ec49b5d3874ea96ff212fc102802327b10affd2ff80a37
   languageName: node
   linkType: hard
 
-"@typescript-eslint/type-utils@npm:7.1.0":
-  version: 7.1.0
-  resolution: "@typescript-eslint/type-utils@npm:7.1.0"
+"@typescript-eslint/type-utils@npm:8.4.0":
+  version: 8.4.0
+  resolution: "@typescript-eslint/type-utils@npm:8.4.0"
   dependencies:
-    "@typescript-eslint/typescript-estree": "npm:7.1.0"
-    "@typescript-eslint/utils": "npm:7.1.0"
+    "@typescript-eslint/typescript-estree": "npm:8.4.0"
+    "@typescript-eslint/utils": "npm:8.4.0"
     debug: "npm:^4.3.4"
-    ts-api-utils: "npm:^1.0.1"
-  peerDependencies:
-    eslint: ^8.56.0
+    ts-api-utils: "npm:^1.3.0"
   peerDependenciesMeta:
     typescript:
       optional: true
-  checksum: 10c0/3e3eea6c03692a643bf4ed11646b0679c6ff13baf1647d97e793f3d8c3adb83061e27a17c2a1470166a3c6c444b974bebc8096d36e0b4b3c36c289ff38bcfc9b
+  checksum: 10c0/ae51100594d9ca61c7577b5aed0bd10c1959725df5c38cd9653eed1fd3dbdfff9146b6e48f3409994b4c8d781b9d95025c36b30f73a5a1b3dbdee6d142cecc87
   languageName: node
   linkType: hard
 
-"@typescript-eslint/types@npm:7.1.0":
-  version: 7.1.0
-  resolution: "@typescript-eslint/types@npm:7.1.0"
-  checksum: 10c0/095cde3e773b7605c5e0c86642002768ced09e94def7f3c6f49a67863f47d7c8ae15413a4ab1a2407f779d1b5ede5fb3000bc98b1cf9ed7ec938acc38cac89e7
+"@typescript-eslint/types@npm:8.4.0":
+  version: 8.4.0
+  resolution: "@typescript-eslint/types@npm:8.4.0"
+  checksum: 10c0/15e09ced84827c349553530a31822f06ae5bad456c03d561b7d0c64b6ad9b5d7ca795e030bd93e65d5a2cd41bfde36ed08dcd2ff9feaa8b60a67080827f47ecb
   languageName: node
   linkType: hard
 
-"@typescript-eslint/typescript-estree@npm:7.1.0":
-  version: 7.1.0
-  resolution: "@typescript-eslint/typescript-estree@npm:7.1.0"
+"@typescript-eslint/typescript-estree@npm:8.4.0":
+  version: 8.4.0
+  resolution: "@typescript-eslint/typescript-estree@npm:8.4.0"
   dependencies:
-    "@typescript-eslint/types": "npm:7.1.0"
-    "@typescript-eslint/visitor-keys": "npm:7.1.0"
+    "@typescript-eslint/types": "npm:8.4.0"
+    "@typescript-eslint/visitor-keys": "npm:8.4.0"
     debug: "npm:^4.3.4"
-    globby: "npm:^11.1.0"
+    fast-glob: "npm:^3.3.2"
     is-glob: "npm:^4.0.3"
-    minimatch: "npm:9.0.3"
-    semver: "npm:^7.5.4"
-    ts-api-utils: "npm:^1.0.1"
+    minimatch: "npm:^9.0.4"
+    semver: "npm:^7.6.0"
+    ts-api-utils: "npm:^1.3.0"
   peerDependenciesMeta:
     typescript:
       optional: true
-  checksum: 10c0/063845dc8526dfda722d1b00960443a5158d1bce2bc39bf49bd353f33f42aa30116105a87b55a04df3eaef99c0d1c13fb987c53848dff43de6152c66dd3ba41c
+  checksum: 10c0/170702b024121cff9268f53de8054796b0ce025f9a78d6f2bc850a360e5f3f7032ba3ee9d4b7392726308273a5f3ade5ab31b1788b504b514bc15afc07302b37
   languageName: node
   linkType: hard
 
-"@typescript-eslint/utils@npm:7.1.0":
-  version: 7.1.0
-  resolution: "@typescript-eslint/utils@npm:7.1.0"
+"@typescript-eslint/utils@npm:8.4.0":
+  version: 8.4.0
+  resolution: "@typescript-eslint/utils@npm:8.4.0"
   dependencies:
     "@eslint-community/eslint-utils": "npm:^4.4.0"
-    "@types/json-schema": "npm:^7.0.12"
-    "@types/semver": "npm:^7.5.0"
-    "@typescript-eslint/scope-manager": "npm:7.1.0"
-    "@typescript-eslint/types": "npm:7.1.0"
-    "@typescript-eslint/typescript-estree": "npm:7.1.0"
-    semver: "npm:^7.5.4"
+    "@typescript-eslint/scope-manager": "npm:8.4.0"
+    "@typescript-eslint/types": "npm:8.4.0"
+    "@typescript-eslint/typescript-estree": "npm:8.4.0"
   peerDependencies:
-    eslint: ^8.56.0
-  checksum: 10c0/3fefd51307d0e294462106c57c4b12cd610bfe1bdcc5ca0142bfac6a5d0d37c18d14be5ec89740eb85515f5512f45219a6048df0efccd457e96f9d0612af4abf
+    eslint: ^8.57.0 || ^9.0.0
+  checksum: 10c0/8c9c36b3aa23f9bcc28cc4b10f0fa2996f1bc6cdd75135f08c2ef734baa30dbd2a8b92f344b90518e1fd07a486936734789fc7e90b780221a7707dad8e9c9364
   languageName: node
   linkType: hard
 
-"@typescript-eslint/visitor-keys@npm:7.1.0":
-  version: 7.1.0
-  resolution: "@typescript-eslint/visitor-keys@npm:7.1.0"
+"@typescript-eslint/visitor-keys@npm:8.4.0":
+  version: 8.4.0
+  resolution: "@typescript-eslint/visitor-keys@npm:8.4.0"
   dependencies:
-    "@typescript-eslint/types": "npm:7.1.0"
-    eslint-visitor-keys: "npm:^3.4.1"
-  checksum: 10c0/9015a10e6ee2a99fc99e0f7a3f274496a813c2c239e868f29e7c0da919c825fe192fe21d3410c43d8a801e8186b51f08ef06523d2c3010570d893a1486ac293d
-  languageName: node
-  linkType: hard
-
-"@ungap/structured-clone@npm:^1.2.0":
-  version: 1.2.0
-  resolution: "@ungap/structured-clone@npm:1.2.0"
-  checksum: 10c0/8209c937cb39119f44eb63cf90c0b73e7c754209a6411c707be08e50e29ee81356dca1a848a405c8bdeebfe2f5e4f831ad310ae1689eeef65e7445c090c6657d
+    "@typescript-eslint/types": "npm:8.4.0"
+    eslint-visitor-keys: "npm:^3.4.3"
+  checksum: 10c0/339199b7fbb9ac83b530d03ab25f6bc5ceb688c9cd0ae460112cd14ee78ca7284a845aef5620cdf70170980123475ec875e85ebf595c60255ba3c0d6fe48c714
   languageName: node
   linkType: hard
 
@@ -619,12 +661,12 @@ __metadata:
   languageName: node
   linkType: hard
 
-"acorn@npm:^8.9.0":
-  version: 8.11.3
-  resolution: "acorn@npm:8.11.3"
+"acorn@npm:^8.12.0":
+  version: 8.12.1
+  resolution: "acorn@npm:8.12.1"
   bin:
     acorn: bin/acorn
-  checksum: 10c0/3ff155f8812e4a746fee8ecff1f227d527c4c45655bb1fad6347c3cb58e46190598217551b1500f18542d2bbe5c87120cb6927f5a074a59166fbdd9468f0a299
+  checksum: 10c0/51fb26cd678f914e13287e886da2d7021f8c2bc0ccc95e03d3e0447ee278dd3b40b9c57dc222acd5881adcf26f3edc40901a4953403232129e3876793cd17386
   languageName: node
   linkType: hard
 
@@ -762,18 +804,18 @@ __metadata:
   languageName: node
   linkType: hard
 
-"bundle-require@npm:^4.0.0":
-  version: 4.0.2
-  resolution: "bundle-require@npm:4.0.2"
+"bundle-require@npm:^5.0.0":
+  version: 5.0.0
+  resolution: "bundle-require@npm:5.0.0"
   dependencies:
     load-tsconfig: "npm:^0.2.3"
   peerDependencies:
-    esbuild: ">=0.17"
-  checksum: 10c0/984735cfcb1c61931e9325220ef8f9684c7d6905be1b45373a7ff42893910121c655f907cc96192a589da66d79a7d6fc8ddf11144628ee1593208a88bbd3929d
+    esbuild: ">=0.18"
+  checksum: 10c0/92c46df02586e0ebd66ee4831c9b5775adb3c32a43fe2b2aaf7bc675135c141f751de6a9a26b146d64c607c5b40f9eef5f10dce3c364f602d4bed268444c32c6
   languageName: node
   linkType: hard
 
-"cac@npm:^6.7.12":
+"cac@npm:^6.7.14":
   version: 6.7.14
   resolution: "cac@npm:6.7.14"
   checksum: 10c0/4ee06aaa7bab8981f0d54e5f5f9d4adcd64058e9697563ce336d8a3878ed018ee18ebe5359b2430eceae87e0758e62ea2019c3f52ae6e211b1bd2e133856cd10
@@ -817,7 +859,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"chokidar@npm:^3.5.1":
+"chokidar@npm:^3.6.0":
   version: 3.6.0
   resolution: "chokidar@npm:3.6.0"
   dependencies:
@@ -880,6 +922,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"consola@npm:^3.2.3":
+  version: 3.2.3
+  resolution: "consola@npm:3.2.3"
+  checksum: 10c0/c606220524ec88a05bb1baf557e9e0e04a0c08a9c35d7a08652d99de195c4ddcb6572040a7df57a18ff38bbc13ce9880ad032d56630cef27bef72768ef0ac078
+  languageName: node
+  linkType: hard
+
 "cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.2, cross-spawn@npm:^7.0.3":
   version: 7.0.3
   resolution: "cross-spawn@npm:7.0.3"
@@ -903,6 +952,18 @@ __metadata:
   languageName: node
   linkType: hard
 
+"debug@npm:^4.3.5":
+  version: 4.3.7
+  resolution: "debug@npm:4.3.7"
+  dependencies:
+    ms: "npm:^2.1.3"
+  peerDependenciesMeta:
+    supports-color:
+      optional: true
+  checksum: 10c0/1471db19c3b06d485a622d62f65947a19a23fbd0dd73f7fd3eafb697eec5360cde447fb075919987899b1a2096e85d35d4eb5a4de09a57600ac9cf7e6c8e768b
+  languageName: node
+  linkType: hard
+
 "deep-is@npm:^0.1.3":
   version: 0.1.4
   resolution: "deep-is@npm:0.1.4"
@@ -919,15 +980,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"doctrine@npm:^3.0.0":
-  version: 3.0.0
-  resolution: "doctrine@npm:3.0.0"
-  dependencies:
-    esutils: "npm:^2.0.2"
-  checksum: 10c0/c96bdccabe9d62ab6fea9399fdff04a66e6563c1d6fb3a3a063e8d53c3bb136ba63e84250bbf63d00086a769ad53aef92d2bd483f03f837fc97b71cbee6b2520
-  languageName: node
-  linkType: hard
-
 "eastasianwidth@npm:^0.2.0":
   version: 0.2.0
   resolution: "eastasianwidth@npm:0.2.0"
@@ -972,33 +1024,34 @@ __metadata:
   languageName: node
   linkType: hard
 
-"esbuild@npm:^0.19.2":
-  version: 0.19.12
-  resolution: "esbuild@npm:0.19.12"
-  dependencies:
-    "@esbuild/aix-ppc64": "npm:0.19.12"
-    "@esbuild/android-arm": "npm:0.19.12"
-    "@esbuild/android-arm64": "npm:0.19.12"
-    "@esbuild/android-x64": "npm:0.19.12"
-    "@esbuild/darwin-arm64": "npm:0.19.12"
-    "@esbuild/darwin-x64": "npm:0.19.12"
-    "@esbuild/freebsd-arm64": "npm:0.19.12"
-    "@esbuild/freebsd-x64": "npm:0.19.12"
-    "@esbuild/linux-arm": "npm:0.19.12"
-    "@esbuild/linux-arm64": "npm:0.19.12"
-    "@esbuild/linux-ia32": "npm:0.19.12"
-    "@esbuild/linux-loong64": "npm:0.19.12"
-    "@esbuild/linux-mips64el": "npm:0.19.12"
-    "@esbuild/linux-ppc64": "npm:0.19.12"
-    "@esbuild/linux-riscv64": "npm:0.19.12"
-    "@esbuild/linux-s390x": "npm:0.19.12"
-    "@esbuild/linux-x64": "npm:0.19.12"
-    "@esbuild/netbsd-x64": "npm:0.19.12"
-    "@esbuild/openbsd-x64": "npm:0.19.12"
-    "@esbuild/sunos-x64": "npm:0.19.12"
-    "@esbuild/win32-arm64": "npm:0.19.12"
-    "@esbuild/win32-ia32": "npm:0.19.12"
-    "@esbuild/win32-x64": "npm:0.19.12"
+"esbuild@npm:^0.23.0":
+  version: 0.23.1
+  resolution: "esbuild@npm:0.23.1"
+  dependencies:
+    "@esbuild/aix-ppc64": "npm:0.23.1"
+    "@esbuild/android-arm": "npm:0.23.1"
+    "@esbuild/android-arm64": "npm:0.23.1"
+    "@esbuild/android-x64": "npm:0.23.1"
+    "@esbuild/darwin-arm64": "npm:0.23.1"
+    "@esbuild/darwin-x64": "npm:0.23.1"
+    "@esbuild/freebsd-arm64": "npm:0.23.1"
+    "@esbuild/freebsd-x64": "npm:0.23.1"
+    "@esbuild/linux-arm": "npm:0.23.1"
+    "@esbuild/linux-arm64": "npm:0.23.1"
+    "@esbuild/linux-ia32": "npm:0.23.1"
+    "@esbuild/linux-loong64": "npm:0.23.1"
+    "@esbuild/linux-mips64el": "npm:0.23.1"
+    "@esbuild/linux-ppc64": "npm:0.23.1"
+    "@esbuild/linux-riscv64": "npm:0.23.1"
+    "@esbuild/linux-s390x": "npm:0.23.1"
+    "@esbuild/linux-x64": "npm:0.23.1"
+    "@esbuild/netbsd-x64": "npm:0.23.1"
+    "@esbuild/openbsd-arm64": "npm:0.23.1"
+    "@esbuild/openbsd-x64": "npm:0.23.1"
+    "@esbuild/sunos-x64": "npm:0.23.1"
+    "@esbuild/win32-arm64": "npm:0.23.1"
+    "@esbuild/win32-ia32": "npm:0.23.1"
+    "@esbuild/win32-x64": "npm:0.23.1"
   dependenciesMeta:
     "@esbuild/aix-ppc64":
       optional: true
@@ -1036,6 +1089,8 @@ __metadata:
       optional: true
     "@esbuild/netbsd-x64":
       optional: true
+    "@esbuild/openbsd-arm64":
+      optional: true
     "@esbuild/openbsd-x64":
       optional: true
     "@esbuild/sunos-x64":
@@ -1048,7 +1103,7 @@ __metadata:
       optional: true
   bin:
     esbuild: bin/esbuild
-  checksum: 10c0/0f2d21ffe24ebead64843f87c3aebe2e703a5ed9feb086a0728b24907fac2eb9923e4a79857d3df9059c915739bd7a870dd667972eae325c67f478b592b8582d
+  checksum: 10c0/08c2ed1105cc3c5e3a24a771e35532fe6089dd24a39c10097899072cef4a99f20860e41e9294e000d86380f353b04d8c50af482483d7f69f5208481cce61eec7
   languageName: node
   linkType: hard
 
@@ -1059,13 +1114,13 @@ __metadata:
   languageName: node
   linkType: hard
 
-"eslint-scope@npm:^7.2.2":
-  version: 7.2.2
-  resolution: "eslint-scope@npm:7.2.2"
+"eslint-scope@npm:^8.0.2":
+  version: 8.0.2
+  resolution: "eslint-scope@npm:8.0.2"
   dependencies:
     esrecurse: "npm:^4.3.0"
     estraverse: "npm:^5.2.0"
-  checksum: 10c0/613c267aea34b5a6d6c00514e8545ef1f1433108097e857225fed40d397dd6b1809dffd11c2fde23b37ca53d7bf935fe04d2a18e6fc932b31837b6ad67e1c116
+  checksum: 10c0/477f820647c8755229da913025b4567347fd1f0bf7cbdf3a256efff26a7e2e130433df052bd9e3d014025423dc00489bea47eb341002b15553673379c1a7dc36
   languageName: node
   linkType: hard
 
@@ -1076,78 +1131,86 @@ __metadata:
   languageName: node
   linkType: hard
 
-"eslint-visitor-keys@npm:^3.4.1, eslint-visitor-keys@npm:^3.4.3":
+"eslint-visitor-keys@npm:^3.4.3":
   version: 3.4.3
   resolution: "eslint-visitor-keys@npm:3.4.3"
   checksum: 10c0/92708e882c0a5ffd88c23c0b404ac1628cf20104a108c745f240a13c332a11aac54f49a22d5762efbffc18ecbc9a580d1b7ad034bf5f3cc3307e5cbff2ec9820
   languageName: node
   linkType: hard
 
-"eslint@npm:^8.57.0":
-  version: 8.57.0
-  resolution: "eslint@npm:8.57.0"
+"eslint-visitor-keys@npm:^4.0.0":
+  version: 4.0.0
+  resolution: "eslint-visitor-keys@npm:4.0.0"
+  checksum: 10c0/76619f42cf162705a1515a6868e6fc7567e185c7063a05621a8ac4c3b850d022661262c21d9f1fc1d144ecf0d5d64d70a3f43c15c3fc969a61ace0fb25698cf5
+  languageName: node
+  linkType: hard
+
+"eslint@npm:^9.10.0":
+  version: 9.10.0
+  resolution: "eslint@npm:9.10.0"
   dependencies:
     "@eslint-community/eslint-utils": "npm:^4.2.0"
-    "@eslint-community/regexpp": "npm:^4.6.1"
-    "@eslint/eslintrc": "npm:^2.1.4"
-    "@eslint/js": "npm:8.57.0"
-    "@humanwhocodes/config-array": "npm:^0.11.14"
+    "@eslint-community/regexpp": "npm:^4.11.0"
+    "@eslint/config-array": "npm:^0.18.0"
+    "@eslint/eslintrc": "npm:^3.1.0"
+    "@eslint/js": "npm:9.10.0"
+    "@eslint/plugin-kit": "npm:^0.1.0"
     "@humanwhocodes/module-importer": "npm:^1.0.1"
+    "@humanwhocodes/retry": "npm:^0.3.0"
     "@nodelib/fs.walk": "npm:^1.2.8"
-    "@ungap/structured-clone": "npm:^1.2.0"
     ajv: "npm:^6.12.4"
     chalk: "npm:^4.0.0"
     cross-spawn: "npm:^7.0.2"
     debug: "npm:^4.3.2"
-    doctrine: "npm:^3.0.0"
     escape-string-regexp: "npm:^4.0.0"
-    eslint-scope: "npm:^7.2.2"
-    eslint-visitor-keys: "npm:^3.4.3"
-    espree: "npm:^9.6.1"
-    esquery: "npm:^1.4.2"
+    eslint-scope: "npm:^8.0.2"
+    eslint-visitor-keys: "npm:^4.0.0"
+    espree: "npm:^10.1.0"
+    esquery: "npm:^1.5.0"
     esutils: "npm:^2.0.2"
     fast-deep-equal: "npm:^3.1.3"
-    file-entry-cache: "npm:^6.0.1"
+    file-entry-cache: "npm:^8.0.0"
     find-up: "npm:^5.0.0"
     glob-parent: "npm:^6.0.2"
-    globals: "npm:^13.19.0"
-    graphemer: "npm:^1.4.0"
     ignore: "npm:^5.2.0"
     imurmurhash: "npm:^0.1.4"
     is-glob: "npm:^4.0.0"
     is-path-inside: "npm:^3.0.3"
-    js-yaml: "npm:^4.1.0"
     json-stable-stringify-without-jsonify: "npm:^1.0.1"
-    levn: "npm:^0.4.1"
     lodash.merge: "npm:^4.6.2"
     minimatch: "npm:^3.1.2"
     natural-compare: "npm:^1.4.0"
     optionator: "npm:^0.9.3"
     strip-ansi: "npm:^6.0.1"
     text-table: "npm:^0.2.0"
+  peerDependencies:
+    jiti: "*"
+  peerDependenciesMeta:
+    jiti:
+      optional: true
   bin:
     eslint: bin/eslint.js
-  checksum: 10c0/00bb96fd2471039a312435a6776fe1fd557c056755eaa2b96093ef3a8508c92c8775d5f754768be6b1dddd09fdd3379ddb231eeb9b6c579ee17ea7d68000a529
+  checksum: 10c0/7357f3995b15043eea83c8c0ab16c385ce3f28925c1b11cfcd6b2ede8faab3d91ede84a68173dd5f6e3e176e177984e6218de58b7b8388e53e2881f1ec07c836
   languageName: node
   linkType: hard
 
-"espree@npm:^9.6.0, espree@npm:^9.6.1":
-  version: 9.6.1
-  resolution: "espree@npm:9.6.1"
+"espree@npm:^10.0.1, espree@npm:^10.1.0":
+  version: 10.1.0
+  resolution: "espree@npm:10.1.0"
   dependencies:
-    acorn: "npm:^8.9.0"
+    acorn: "npm:^8.12.0"
     acorn-jsx: "npm:^5.3.2"
-    eslint-visitor-keys: "npm:^3.4.1"
-  checksum: 10c0/1a2e9b4699b715347f62330bcc76aee224390c28bb02b31a3752e9d07549c473f5f986720483c6469cf3cfb3c9d05df612ffc69eb1ee94b54b739e67de9bb460
+    eslint-visitor-keys: "npm:^4.0.0"
+  checksum: 10c0/52e6feaa77a31a6038f0c0e3fce93010a4625701925b0715cd54a2ae190b3275053a0717db698697b32653788ac04845e489d6773b508d6c2e8752f3c57470a0
   languageName: node
   linkType: hard
 
-"esquery@npm:^1.4.2":
-  version: 1.5.0
-  resolution: "esquery@npm:1.5.0"
+"esquery@npm:^1.5.0":
+  version: 1.6.0
+  resolution: "esquery@npm:1.6.0"
   dependencies:
     estraverse: "npm:^5.1.0"
-  checksum: 10c0/a084bd049d954cc88ac69df30534043fb2aee5555b56246493f42f27d1e168f00d9e5d4192e46f10290d312dc30dc7d58994d61a609c579c1219d636996f9213
+  checksum: 10c0/cb9065ec605f9da7a76ca6dadb0619dfb611e37a81e318732977d90fab50a256b95fee2d925fba7c2f3f0523aa16f91587246693bc09bc34d5a59575fe6e93d2
   languageName: node
   linkType: hard
 
@@ -1174,7 +1237,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"execa@npm:^5.0.0":
+"execa@npm:^5.1.1":
   version: 5.1.1
   resolution: "execa@npm:5.1.1"
   dependencies:
@@ -1235,6 +1298,19 @@ __metadata:
   languageName: node
   linkType: hard
 
+"fast-glob@npm:^3.3.2":
+  version: 3.3.2
+  resolution: "fast-glob@npm:3.3.2"
+  dependencies:
+    "@nodelib/fs.stat": "npm:^2.0.2"
+    "@nodelib/fs.walk": "npm:^1.2.3"
+    glob-parent: "npm:^5.1.2"
+    merge2: "npm:^1.3.0"
+    micromatch: "npm:^4.0.4"
+  checksum: 10c0/42baad7b9cd40b63e42039132bde27ca2cb3a4950d0a0f9abe4639ea1aa9d3e3b40f98b1fe31cbc0cc17b664c9ea7447d911a152fa34ec5b72977b125a6fc845
+  languageName: node
+  linkType: hard
+
 "fast-json-stable-stringify@npm:^2.0.0":
   version: 2.1.0
   resolution: "fast-json-stable-stringify@npm:2.1.0"
@@ -1258,12 +1334,12 @@ __metadata:
   languageName: node
   linkType: hard
 
-"file-entry-cache@npm:^6.0.1":
-  version: 6.0.1
-  resolution: "file-entry-cache@npm:6.0.1"
+"file-entry-cache@npm:^8.0.0":
+  version: 8.0.0
+  resolution: "file-entry-cache@npm:8.0.0"
   dependencies:
-    flat-cache: "npm:^3.0.4"
-  checksum: 10c0/58473e8a82794d01b38e5e435f6feaf648e3f36fdb3a56e98f417f4efae71ad1c0d4ebd8a9a7c50c3ad085820a93fc7494ad721e0e4ebc1da3573f4e1c3c7cdd
+    flat-cache: "npm:^4.0.0"
+  checksum: 10c0/9e2b5938b1cd9b6d7e3612bdc533afd4ac17b2fc646569e9a8abbf2eb48e5eb8e316bc38815a3ef6a1b456f4107f0d0f055a614ca613e75db6bf9ff4d72c1638
   languageName: node
   linkType: hard
 
@@ -1286,20 +1362,20 @@ __metadata:
   languageName: node
   linkType: hard
 
-"flat-cache@npm:^3.0.4":
-  version: 3.0.4
-  resolution: "flat-cache@npm:3.0.4"
+"flat-cache@npm:^4.0.0":
+  version: 4.0.1
+  resolution: "flat-cache@npm:4.0.1"
   dependencies:
-    flatted: "npm:^3.1.0"
-    rimraf: "npm:^3.0.2"
-  checksum: 10c0/f274dcbadb09ad8d7b6edf2ee9b034bc40bf0c12638f6c4084e9f1d39208cb104a5ebbb24b398880ef048200eaa116852f73d2d8b72e8c9627aba8c3e27ca057
+    flatted: "npm:^3.2.9"
+    keyv: "npm:^4.5.4"
+  checksum: 10c0/2c59d93e9faa2523e4fda6b4ada749bed432cfa28c8e251f33b25795e426a1c6dbada777afb1f74fcfff33934fdbdea921ee738fcc33e71adc9d6eca984a1cfc
   languageName: node
   linkType: hard
 
-"flatted@npm:^3.1.0":
-  version: 3.2.7
-  resolution: "flatted@npm:3.2.7"
-  checksum: 10c0/207a87c7abfc1ea6928ea16bac84f9eaa6d44d365620ece419e5c41cf44a5e9902b4c1f59c9605771b10e4565a0cb46e99d78e0464e8aabb42c97de880642257
+"flatted@npm:^3.2.9":
+  version: 3.3.1
+  resolution: "flatted@npm:3.3.1"
+  checksum: 10c0/324166b125ee07d4ca9bcf3a5f98d915d5db4f39d711fba640a3178b959919aae1f7cfd8aabcfef5826ed8aa8a2aa14cc85b2d7d18ff638ddf4ae3df39573eaf
   languageName: node
   linkType: hard
 
@@ -1331,13 +1407,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"fs.realpath@npm:^1.0.0":
-  version: 1.0.0
-  resolution: "fs.realpath@npm:1.0.0"
-  checksum: 10c0/444cf1291d997165dfd4c0d58b69f0e4782bfd9149fd72faa4fe299e68e0e93d6db941660b37dd29153bf7186672ececa3b50b7e7249477b03fdf850f287c948
-  languageName: node
-  linkType: hard
-
 "fsevents@npm:~2.3.2":
   version: 2.3.3
   resolution: "fsevents@npm:2.3.3"
@@ -1417,10 +1486,12 @@ __metadata:
   version: 0.0.0-use.local
   resolution: "git-cliff@workspace:."
   dependencies:
-    "@types/node": "npm:^20.11.22"
-    "@typescript-eslint/eslint-plugin": "npm:^7.1.0"
-    "@typescript-eslint/parser": "npm:^7.1.0"
-    eslint: "npm:^8.57.0"
+    "@eslint/js": "npm:^9.10.0"
+    "@types/eslint__js": "npm:^8.42.3"
+    "@types/node": "npm:^20.16.5"
+    "@typescript-eslint/eslint-plugin": "npm:^8.4.0"
+    "@typescript-eslint/parser": "npm:^8.4.0"
+    eslint: "npm:^9.10.0"
     execa: "npm:^8.0.1"
     git-cliff-darwin-arm64: "npm:2.5.0"
     git-cliff-darwin-x64: "npm:2.5.0"
@@ -1428,8 +1499,9 @@ __metadata:
     git-cliff-linux-x64: "npm:2.5.0"
     git-cliff-windows-arm64: "npm:2.5.0"
     git-cliff-windows-x64: "npm:2.5.0"
-    tsup: "npm:^8.0.2"
-    typescript: "npm:^5.3.3"
+    tsup: "npm:^8.2.4"
+    typescript: "npm:^5.5.4"
+    typescript-eslint: "npm:^8.4.0"
   dependenciesMeta:
     git-cliff-darwin-arm64:
       optional: true
@@ -1481,30 +1553,14 @@ __metadata:
   languageName: node
   linkType: hard
 
-"glob@npm:^7.1.3":
-  version: 7.2.3
-  resolution: "glob@npm:7.2.3"
-  dependencies:
-    fs.realpath: "npm:^1.0.0"
-    inflight: "npm:^1.0.4"
-    inherits: "npm:2"
-    minimatch: "npm:^3.1.1"
-    once: "npm:^1.3.0"
-    path-is-absolute: "npm:^1.0.0"
-  checksum: 10c0/65676153e2b0c9095100fe7f25a778bf45608eeb32c6048cf307f579649bcc30353277b3b898a3792602c65764e5baa4f643714dfbdfd64ea271d210c7a425fe
-  languageName: node
-  linkType: hard
-
-"globals@npm:^13.19.0":
-  version: 13.19.0
-  resolution: "globals@npm:13.19.0"
-  dependencies:
-    type-fest: "npm:^0.20.2"
-  checksum: 10c0/d2bb3164ed9f5ec82b91e96d6a5ffc1cca3cb10f6c41df9687cd7712ba82f5534ed028b11c5717d71c938403bf8ffc97bb06f5f2eab8c1b91e6273b08b33b5e6
+"globals@npm:^14.0.0":
+  version: 14.0.0
+  resolution: "globals@npm:14.0.0"
+  checksum: 10c0/b96ff42620c9231ad468d4c58ff42afee7777ee1c963013ff8aabe095a451d0ceeb8dcd8ef4cbd64d2538cef45f787a78ba3a9574f4a634438963e334471302d
   languageName: node
   linkType: hard
 
-"globby@npm:^11.0.3, globby@npm:^11.1.0":
+"globby@npm:^11.1.0":
   version: 11.1.0
   resolution: "globby@npm:11.1.0"
   dependencies:
@@ -1596,10 +1652,10 @@ __metadata:
   languageName: node
   linkType: hard
 
-"ignore@npm:^5.2.4":
-  version: 5.3.1
-  resolution: "ignore@npm:5.3.1"
-  checksum: 10c0/703f7f45ffb2a27fb2c5a8db0c32e7dee66b33a225d28e8db4e1be6474795f606686a6e3bcc50e1aa12f2042db4c9d4a7d60af3250511de74620fbed052ea4cd
+"ignore@npm:^5.3.1":
+  version: 5.3.2
+  resolution: "ignore@npm:5.3.2"
+  checksum: 10c0/f9f652c957983634ded1e7f02da3b559a0d4cc210fca3792cb67f1b153623c9c42efdc1c4121af171e295444459fc4a9201101fb041b1104a3c000bccb188337
   languageName: node
   linkType: hard
 
@@ -1627,23 +1683,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"inflight@npm:^1.0.4":
-  version: 1.0.6
-  resolution: "inflight@npm:1.0.6"
-  dependencies:
-    once: "npm:^1.3.0"
-    wrappy: "npm:1"
-  checksum: 10c0/7faca22584600a9dc5b9fca2cd5feb7135ac8c935449837b315676b4c90aa4f391ec4f42240178244b5a34e8bede1948627fda392ca3191522fc46b34e985ab2
-  languageName: node
-  linkType: hard
-
-"inherits@npm:2":
-  version: 2.0.4
-  resolution: "inherits@npm:2.0.4"
-  checksum: 10c0/4e531f648b29039fb7426fb94075e6545faa1eb9fe83c29f0b6d9e7263aceb4289d2d4557db0d428188eeb449cc7c5e77b0a0b2c4e248ff2a65933a0dee49ef2
-  languageName: node
-  linkType: hard
-
 "ip-address@npm:^9.0.5":
   version: 9.0.5
   resolution: "ip-address@npm:9.0.5"
@@ -1748,7 +1787,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"joycon@npm:^3.0.1":
+"joycon@npm:^3.1.1":
   version: 3.1.1
   resolution: "joycon@npm:3.1.1"
   checksum: 10c0/131fb1e98c9065d067fd49b6e685487ac4ad4d254191d7aa2c9e3b90f4e9ca70430c43cad001602bdbdabcf58717d3b5c5b7461c1bd8e39478c8de706b3fe6ae
@@ -1773,6 +1812,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"json-buffer@npm:3.0.1":
+  version: 3.0.1
+  resolution: "json-buffer@npm:3.0.1"
+  checksum: 10c0/0d1c91569d9588e7eef2b49b59851f297f3ab93c7b35c7c221e288099322be6b562767d11e4821da500f3219542b9afd2e54c5dc573107c1126ed1080f8e96d7
+  languageName: node
+  linkType: hard
+
 "json-schema-traverse@npm:^0.4.1":
   version: 0.4.1
   resolution: "json-schema-traverse@npm:0.4.1"
@@ -1787,6 +1833,15 @@ __metadata:
   languageName: node
   linkType: hard
 
+"keyv@npm:^4.5.4":
+  version: 4.5.4
+  resolution: "keyv@npm:4.5.4"
+  dependencies:
+    json-buffer: "npm:3.0.1"
+  checksum: 10c0/aa52f3c5e18e16bb6324876bb8b59dd02acf782a4b789c7b2ae21107fab95fab3890ed448d4f8dba80ce05391eeac4bfabb4f02a20221342982f806fa2cf271e
+  languageName: node
+  linkType: hard
+
 "levn@npm:^0.4.1":
   version: 0.4.1
   resolution: "levn@npm:0.4.1"
@@ -1797,10 +1852,10 @@ __metadata:
   languageName: node
   linkType: hard
 
-"lilconfig@npm:^3.0.0":
-  version: 3.1.1
-  resolution: "lilconfig@npm:3.1.1"
-  checksum: 10c0/311b559794546894e3fe176663427326026c1c644145be9e8041c58e268aa9328799b8dfe7e4dd8c6a4ae305feae95a1c9e007db3569f35b42b6e1bc8274754c
+"lilconfig@npm:^3.1.1":
+  version: 3.1.2
+  resolution: "lilconfig@npm:3.1.2"
+  checksum: 10c0/f059630b1a9bddaeba83059db00c672b64dc14074e9f232adce32b38ca1b5686ab737eb665c5ba3c32f147f0002b4bee7311ad0386a9b98547b5623e87071fbe
   languageName: node
   linkType: hard
 
@@ -1914,7 +1969,16 @@ __metadata:
   languageName: node
   linkType: hard
 
-"minimatch@npm:9.0.3, minimatch@npm:^9.0.1":
+"minimatch@npm:^3.1.2":
+  version: 3.1.2
+  resolution: "minimatch@npm:3.1.2"
+  dependencies:
+    brace-expansion: "npm:^1.1.7"
+  checksum: 10c0/0262810a8fc2e72cca45d6fd86bd349eee435eb95ac6aa45c9ea2180e7ee875ef44c32b55b5973ceabe95ea12682f6e3725cbb63d7a2d1da3ae1163c8b210311
+  languageName: node
+  linkType: hard
+
+"minimatch@npm:^9.0.1":
   version: 9.0.3
   resolution: "minimatch@npm:9.0.3"
   dependencies:
@@ -1923,12 +1987,12 @@ __metadata:
   languageName: node
   linkType: hard
 
-"minimatch@npm:^3.0.5, minimatch@npm:^3.1.1, minimatch@npm:^3.1.2":
-  version: 3.1.2
-  resolution: "minimatch@npm:3.1.2"
+"minimatch@npm:^9.0.4":
+  version: 9.0.5
+  resolution: "minimatch@npm:9.0.5"
   dependencies:
-    brace-expansion: "npm:^1.1.7"
-  checksum: 10c0/0262810a8fc2e72cca45d6fd86bd349eee435eb95ac6aa45c9ea2180e7ee875ef44c32b55b5973ceabe95ea12682f6e3725cbb63d7a2d1da3ae1163c8b210311
+    brace-expansion: "npm:^2.0.1"
+  checksum: 10c0/de96cf5e35bdf0eab3e2c853522f98ffbe9a36c37797778d2665231ec1f20a9447a7e567cb640901f89e4daaa95ae5d70c65a9e8aa2bb0019b6facbc3c0575ed
   languageName: node
   linkType: hard
 
@@ -2032,6 +2096,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"ms@npm:^2.1.3":
+  version: 2.1.3
+  resolution: "ms@npm:2.1.3"
+  checksum: 10c0/d924b57e7312b3b63ad21fc5b3dc0af5e78d61a1fc7cfb5457edaf26326bf62be5307cc87ffb6862ef1c2b33b0233cdb5d4f01c4c958cc0d660948b65a287a48
+  languageName: node
+  linkType: hard
+
 "mz@npm:^2.7.0":
   version: 2.7.0
   resolution: "mz@npm:2.7.0"
@@ -2120,15 +2191,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"once@npm:^1.3.0":
-  version: 1.4.0
-  resolution: "once@npm:1.4.0"
-  dependencies:
-    wrappy: "npm:1"
-  checksum: 10c0/5d48aca287dfefabd756621c5dfce5c91a549a93e9fdb7b8246bc4c4790aa2ec17b34a260530474635147aeb631a2dcc8b32c613df0675f96041cbb8244517d0
-  languageName: node
-  linkType: hard
-
 "onetime@npm:^5.1.2":
   version: 5.1.2
   resolution: "onetime@npm:5.1.2"
@@ -2204,13 +2266,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"path-is-absolute@npm:^1.0.0":
-  version: 1.0.1
-  resolution: "path-is-absolute@npm:1.0.1"
-  checksum: 10c0/127da03c82172a2a50099cddbf02510c1791fc2cc5f7713ddb613a56838db1e8168b121a920079d052e0936c23005562059756d653b7c544c53185efe53be078
-  languageName: node
-  linkType: hard
-
 "path-key@npm:^3.0.0, path-key@npm:^3.1.0":
   version: 3.1.1
   resolution: "path-key@npm:3.1.1"
@@ -2242,6 +2297,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"picocolors@npm:^1.0.1":
+  version: 1.1.0
+  resolution: "picocolors@npm:1.1.0"
+  checksum: 10c0/86946f6032148801ef09c051c6fb13b5cf942eaf147e30ea79edb91dd32d700934edebe782a1078ff859fb2b816792e97ef4dab03d7f0b804f6b01a0df35e023
+  languageName: node
+  linkType: hard
+
 "picomatch@npm:^2.0.4, picomatch@npm:^2.2.1, picomatch@npm:^2.3.1":
   version: 2.3.1
   resolution: "picomatch@npm:2.3.1"
@@ -2256,21 +2318,26 @@ __metadata:
   languageName: node
   linkType: hard
 
-"postcss-load-config@npm:^4.0.1":
-  version: 4.0.2
-  resolution: "postcss-load-config@npm:4.0.2"
+"postcss-load-config@npm:^6.0.1":
+  version: 6.0.1
+  resolution: "postcss-load-config@npm:6.0.1"
   dependencies:
-    lilconfig: "npm:^3.0.0"
-    yaml: "npm:^2.3.4"
+    lilconfig: "npm:^3.1.1"
   peerDependencies:
+    jiti: ">=1.21.0"
     postcss: ">=8.0.9"
-    ts-node: ">=9.0.0"
+    tsx: ^4.8.1
+    yaml: ^2.4.2
   peerDependenciesMeta:
+    jiti:
+      optional: true
     postcss:
       optional: true
-    ts-node:
+    tsx:
+      optional: true
+    yaml:
       optional: true
-  checksum: 10c0/3d7939acb3570b0e4b4740e483d6e555a3e2de815219cb8a3c8fc03f575a6bde667443aa93369c0be390af845cb84471bf623e24af833260de3a105b78d42519
+  checksum: 10c0/74173a58816dac84e44853f7afbd283f4ef13ca0b6baeba27701214beec33f9e309b128f8102e2b173e8d45ecba45d279a9be94b46bf48d219626aa9b5730848
   languageName: node
   linkType: hard
 
@@ -2349,34 +2416,26 @@ __metadata:
   languageName: node
   linkType: hard
 
-"rimraf@npm:^3.0.2":
-  version: 3.0.2
-  resolution: "rimraf@npm:3.0.2"
-  dependencies:
-    glob: "npm:^7.1.3"
-  bin:
-    rimraf: bin.js
-  checksum: 10c0/9cb7757acb489bd83757ba1a274ab545eafd75598a9d817e0c3f8b164238dd90eba50d6b848bd4dcc5f3040912e882dc7ba71653e35af660d77b25c381d402e8
-  languageName: node
-  linkType: hard
-
-"rollup@npm:^4.0.2":
-  version: 4.12.0
-  resolution: "rollup@npm:4.12.0"
-  dependencies:
-    "@rollup/rollup-android-arm-eabi": "npm:4.12.0"
-    "@rollup/rollup-android-arm64": "npm:4.12.0"
-    "@rollup/rollup-darwin-arm64": "npm:4.12.0"
-    "@rollup/rollup-darwin-x64": "npm:4.12.0"
-    "@rollup/rollup-linux-arm-gnueabihf": "npm:4.12.0"
-    "@rollup/rollup-linux-arm64-gnu": "npm:4.12.0"
-    "@rollup/rollup-linux-arm64-musl": "npm:4.12.0"
-    "@rollup/rollup-linux-riscv64-gnu": "npm:4.12.0"
-    "@rollup/rollup-linux-x64-gnu": "npm:4.12.0"
-    "@rollup/rollup-linux-x64-musl": "npm:4.12.0"
-    "@rollup/rollup-win32-arm64-msvc": "npm:4.12.0"
-    "@rollup/rollup-win32-ia32-msvc": "npm:4.12.0"
-    "@rollup/rollup-win32-x64-msvc": "npm:4.12.0"
+"rollup@npm:^4.19.0":
+  version: 4.21.2
+  resolution: "rollup@npm:4.21.2"
+  dependencies:
+    "@rollup/rollup-android-arm-eabi": "npm:4.21.2"
+    "@rollup/rollup-android-arm64": "npm:4.21.2"
+    "@rollup/rollup-darwin-arm64": "npm:4.21.2"
+    "@rollup/rollup-darwin-x64": "npm:4.21.2"
+    "@rollup/rollup-linux-arm-gnueabihf": "npm:4.21.2"
+    "@rollup/rollup-linux-arm-musleabihf": "npm:4.21.2"
+    "@rollup/rollup-linux-arm64-gnu": "npm:4.21.2"
+    "@rollup/rollup-linux-arm64-musl": "npm:4.21.2"
+    "@rollup/rollup-linux-powerpc64le-gnu": "npm:4.21.2"
+    "@rollup/rollup-linux-riscv64-gnu": "npm:4.21.2"
+    "@rollup/rollup-linux-s390x-gnu": "npm:4.21.2"
+    "@rollup/rollup-linux-x64-gnu": "npm:4.21.2"
+    "@rollup/rollup-linux-x64-musl": "npm:4.21.2"
+    "@rollup/rollup-win32-arm64-msvc": "npm:4.21.2"
+    "@rollup/rollup-win32-ia32-msvc": "npm:4.21.2"
+    "@rollup/rollup-win32-x64-msvc": "npm:4.21.2"
     "@types/estree": "npm:1.0.5"
     fsevents: "npm:~2.3.2"
   dependenciesMeta:
@@ -2390,12 +2449,18 @@ __metadata:
       optional: true
     "@rollup/rollup-linux-arm-gnueabihf":
       optional: true
+    "@rollup/rollup-linux-arm-musleabihf":
+      optional: true
     "@rollup/rollup-linux-arm64-gnu":
       optional: true
     "@rollup/rollup-linux-arm64-musl":
       optional: true
+    "@rollup/rollup-linux-powerpc64le-gnu":
+      optional: true
     "@rollup/rollup-linux-riscv64-gnu":
       optional: true
+    "@rollup/rollup-linux-s390x-gnu":
+      optional: true
     "@rollup/rollup-linux-x64-gnu":
       optional: true
     "@rollup/rollup-linux-x64-musl":
@@ -2410,7 +2475,7 @@ __metadata:
       optional: true
   bin:
     rollup: dist/bin/rollup
-  checksum: 10c0/1650168231ae8e2bd6fb4d82cc232e53b5c0fe67895188fa683370c9bd3f1febaa28e45c6b100cea333e54f8f5fae6f4d0eea7d86256ec2cc3e38212c55796d6
+  checksum: 10c0/c9d97f7a21cde110371b2e890a31a996fee09b81e639e79372b962a9638ae653d2d24186b94632fc5dfab8a0582e1d0639dfe34b8b75051facd86915a9585a5f
   languageName: node
   linkType: hard
 
@@ -2430,7 +2495,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"semver@npm:^7.3.5, semver@npm:^7.5.4":
+"semver@npm:^7.3.5":
   version: 7.6.0
   resolution: "semver@npm:7.6.0"
   dependencies:
@@ -2441,6 +2506,15 @@ __metadata:
   languageName: node
   linkType: hard
 
+"semver@npm:^7.6.0":
+  version: 7.6.3
+  resolution: "semver@npm:7.6.3"
+  bin:
+    semver: bin/semver.js
+  checksum: 10c0/88f33e148b210c153873cb08cfe1e281d518aaa9a666d4d148add6560db5cd3c582f3a08ccb91f38d5f379ead256da9931234ed122057f40bb5766e65e58adaf
+  languageName: node
+  linkType: hard
+
 "shebang-command@npm:^2.0.0":
   version: 2.0.0
   resolution: "shebang-command@npm:2.0.0"
@@ -2592,7 +2666,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"sucrase@npm:^3.20.3":
+"sucrase@npm:^3.35.0":
   version: 3.35.0
   resolution: "sucrase@npm:3.35.0"
   dependencies:
@@ -2685,12 +2759,12 @@ __metadata:
   languageName: node
   linkType: hard
 
-"ts-api-utils@npm:^1.0.1":
-  version: 1.2.1
-  resolution: "ts-api-utils@npm:1.2.1"
+"ts-api-utils@npm:^1.3.0":
+  version: 1.3.0
+  resolution: "ts-api-utils@npm:1.3.0"
   peerDependencies:
     typescript: ">=4.2.0"
-  checksum: 10c0/8ddb493e7ae581d3f57a2e469142feb60b420d4ad8366ab969fe8e36531f8f301f370676b47e8d97f28b5f5fd10d6f2d55f656943a8546ef95e35ce5cf117754
+  checksum: 10c0/f54a0ba9ed56ce66baea90a3fa087a484002e807f28a8ccb2d070c75e76bde64bd0f6dce98b3802834156306050871b67eec325cb4e918015a360a3f0868c77c
   languageName: node
   linkType: hard
 
@@ -2701,23 +2775,25 @@ __metadata:
   languageName: node
   linkType: hard
 
-"tsup@npm:^8.0.2":
-  version: 8.0.2
-  resolution: "tsup@npm:8.0.2"
+"tsup@npm:^8.2.4":
+  version: 8.2.4
+  resolution: "tsup@npm:8.2.4"
   dependencies:
-    bundle-require: "npm:^4.0.0"
-    cac: "npm:^6.7.12"
-    chokidar: "npm:^3.5.1"
-    debug: "npm:^4.3.1"
-    esbuild: "npm:^0.19.2"
-    execa: "npm:^5.0.0"
-    globby: "npm:^11.0.3"
-    joycon: "npm:^3.0.1"
-    postcss-load-config: "npm:^4.0.1"
+    bundle-require: "npm:^5.0.0"
+    cac: "npm:^6.7.14"
+    chokidar: "npm:^3.6.0"
+    consola: "npm:^3.2.3"
+    debug: "npm:^4.3.5"
+    esbuild: "npm:^0.23.0"
+    execa: "npm:^5.1.1"
+    globby: "npm:^11.1.0"
+    joycon: "npm:^3.1.1"
+    picocolors: "npm:^1.0.1"
+    postcss-load-config: "npm:^6.0.1"
     resolve-from: "npm:^5.0.0"
-    rollup: "npm:^4.0.2"
+    rollup: "npm:^4.19.0"
     source-map: "npm:0.8.0-beta.0"
-    sucrase: "npm:^3.20.3"
+    sucrase: "npm:^3.35.0"
     tree-kill: "npm:^1.2.2"
   peerDependencies:
     "@microsoft/api-extractor": ^7.36.0
@@ -2736,7 +2812,7 @@ __metadata:
   bin:
     tsup: dist/cli-default.js
     tsup-node: dist/cli-node.js
-  checksum: 10c0/de3e8b2d9a7a504afb9394f2409ef88fd21dd338a78ebb572dd5c1719d73db816baa7ae4b7867016f08ba6a67560daec13a85768efff1d70e380972e39e27ce6
+  checksum: 10c0/0fa967ae0feb483528ae52fd9988d7931a092b3645a456e23b62ac03a0556da6f569fb2a77b3baf50ff1d12b9afac38aa9d29f15eb82c8a2b4faeda8362858da
   languageName: node
   linkType: hard
 
@@ -2749,37 +2825,44 @@ __metadata:
   languageName: node
   linkType: hard
 
-"type-fest@npm:^0.20.2":
-  version: 0.20.2
-  resolution: "type-fest@npm:0.20.2"
-  checksum: 10c0/dea9df45ea1f0aaa4e2d3bed3f9a0bfe9e5b2592bddb92eb1bf06e50bcf98dbb78189668cd8bc31a0511d3fc25539b4cd5c704497e53e93e2d40ca764b10bfc3
+"typescript-eslint@npm:^8.4.0":
+  version: 8.4.0
+  resolution: "typescript-eslint@npm:8.4.0"
+  dependencies:
+    "@typescript-eslint/eslint-plugin": "npm:8.4.0"
+    "@typescript-eslint/parser": "npm:8.4.0"
+    "@typescript-eslint/utils": "npm:8.4.0"
+  peerDependenciesMeta:
+    typescript:
+      optional: true
+  checksum: 10c0/266ef73fdc1f7fa19228b8653d61ad143261ccd35f7d5d647092ed0e1512de2d4e3d1b9e1f2520658708cc0c1d7925c4ec97f23440c180a3bf1716e81d65123f
   languageName: node
   linkType: hard
 
-"typescript@npm:^5.3.3":
-  version: 5.3.3
-  resolution: "typescript@npm:5.3.3"
+"typescript@npm:^5.5.4":
+  version: 5.5.4
+  resolution: "typescript@npm:5.5.4"
   bin:
     tsc: bin/tsc
     tsserver: bin/tsserver
-  checksum: 10c0/e33cef99d82573624fc0f854a2980322714986bc35b9cb4d1ce736ed182aeab78e2cb32b385efa493b2a976ef52c53e20d6c6918312353a91850e2b76f1ea44f
+  checksum: 10c0/422be60f89e661eab29ac488c974b6cc0a660fb2228003b297c3d10c32c90f3bcffc1009b43876a082515a3c376b1eefcce823d6e78982e6878408b9a923199c
   languageName: node
   linkType: hard
 
-"typescript@patch:typescript@npm%3A^5.3.3#optional!builtin<compat/typescript>":
-  version: 5.3.3
-  resolution: "typescript@patch:typescript@npm%3A5.3.3#optional!builtin<compat/typescript>::version=5.3.3&hash=e012d7"
+"typescript@patch:typescript@npm%3A^5.5.4#optional!builtin<compat/typescript>":
+  version: 5.5.4
+  resolution: "typescript@patch:typescript@npm%3A5.5.4#optional!builtin<compat/typescript>::version=5.5.4&hash=d69c25"
   bin:
     tsc: bin/tsc
     tsserver: bin/tsserver
-  checksum: 10c0/1d0a5f4ce496c42caa9a30e659c467c5686eae15d54b027ee7866744952547f1be1262f2d40de911618c242b510029d51d43ff605dba8fb740ec85ca2d3f9500
+  checksum: 10c0/10dd9881baba22763de859e8050d6cb6e2db854197495c6f1929b08d1eb2b2b00d0b5d9b0bcee8472f1c3f4a7ef6a5d7ebe0cfd703f853aa5ae465b8404bc1ba
   languageName: node
   linkType: hard
 
-"undici-types@npm:~5.26.4":
-  version: 5.26.5
-  resolution: "undici-types@npm:5.26.5"
-  checksum: 10c0/bb673d7876c2d411b6eb6c560e0c571eef4a01c1c19925175d16e3a30c4c428181fb8d7ae802a261f283e4166a0ac435e2f505743aa9e45d893f9a3df017b501
+"undici-types@npm:~6.19.2":
+  version: 6.19.8
+  resolution: "undici-types@npm:6.19.8"
+  checksum: 10c0/078afa5990fba110f6824823ace86073b4638f1d5112ee26e790155f481f2a868cc3e0615505b6f4282bdf74a3d8caad715fd809e870c2bb0704e3ea6082f344
   languageName: node
   linkType: hard
 
@@ -2872,13 +2955,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"wrappy@npm:1":
-  version: 1.0.2
-  resolution: "wrappy@npm:1.0.2"
-  checksum: 10c0/56fece1a4018c6a6c8e28fbc88c87e0fbf4ea8fd64fc6c63b18f4acc4bd13e0ad2515189786dd2c30d3eec9663d70f4ecf699330002f8ccb547e4a18231fc9f0
-  languageName: node
-  linkType: hard
-
 "yallist@npm:^4.0.0":
   version: 4.0.0
   resolution: "yallist@npm:4.0.0"
@@ -2886,15 +2962,6 @@ __metadata:
   languageName: node
   linkType: hard
 
-"yaml@npm:^2.3.4":
-  version: 2.4.0
-  resolution: "yaml@npm:2.4.0"
-  bin:
-    yaml: bin.mjs
-  checksum: 10c0/97ab0b5a0714c92e4dd75120a6a63e470b0adc282afae0a701bf38f8c42cbf6429fcd6aca883e3a63c68936ab841862e6c69e2d66d355c3e4fc7cfd346af2108
-  languageName: node
-  linkType: hard
-
 "yocto-queue@npm:^0.1.0":
   version: 0.1.0
   resolution: "yocto-queue@npm:0.1.0"
diff --git a/website/docs/integration/bitbucket.md b/website/docs/integration/bitbucket.md
index 7295bb9..cf283a8 100644
--- a/website/docs/integration/bitbucket.md
+++ b/website/docs/integration/bitbucket.md
@@ -104,7 +104,7 @@ For each commit, Bitbucket related values are added as a nested object (named `b
 
   "...": "<strip>",
 
-  "bitbucket": {
+  "remote": {
     "username": "orhun",
     "pr_title": "some things have changed",
     "pr_number": 420,
@@ -119,8 +119,8 @@ This can be used in the template as follows:
 ```
 {% for commit in commits %}
   * {{ commit.message | split(pat="\n") | first | trim }}\
-    {% if commit.bitbucket.username %} by @{{ commit.bitbucket.username }}{%- endif %}\
-    {% if commit.bitbucket.pr_number %} in #{{ commit.bitbucket.pr_number }}{%- endif %}
+    {% if commit.remote.username %} by @{{ commit.remote.username }}{%- endif %}\
+    {% if commit.remote.pr_number %} in #{{ commit.remote.pr_number }}{%- endif %}
 {%- endfor -%}
 ```
 
diff --git a/website/docs/integration/gitea.md b/website/docs/integration/gitea.md
index 8020bd2..1d355c7 100644
--- a/website/docs/integration/gitea.md
+++ b/website/docs/integration/gitea.md
@@ -104,7 +104,7 @@ For each commit, Gitea related values are added as a nested object (named `gitea
 
   "...": "<strip>",
 
-  "gitea": {
+  "remote": {
     "username": "orhun",
     "pr_title": "some things have changed",
     "pr_number": 420,
@@ -119,8 +119,8 @@ This can be used in the template as follows:
 ```
 {% for commit in commits %}
   * {{ commit.message | split(pat="\n") | first | trim }}\
-    {% if commit.gitea.username %} by @{{ commit.gitea.username }}{%- endif %}\
-    {% if commit.gitea.pr_number %} in #{{ commit.gitea.pr_number }}{%- endif %}
+    {% if commit.remote.username %} by @{{ commit.remote.username }}{%- endif %}\
+    {% if commit.remote.pr_number %} in #{{ commit.remote.pr_number }}{%- endif %}
 {%- endfor -%}
 ```
 
diff --git a/website/docs/integration/github.md b/website/docs/integration/github.md
index d71e992..5afdec6 100644
--- a/website/docs/integration/github.md
+++ b/website/docs/integration/github.md
@@ -108,7 +108,7 @@ For each commit, GitHub related values are added as a nested object (named `gith
 
   "...": "<strip>",
 
-  "github": {
+  "remote": {
     "username": "orhun",
     "pr_title": "some things have changed",
     "pr_number": 420,
@@ -123,8 +123,8 @@ This can be used in the template as follows:
 ```
 {% for commit in commits %}
   * {{ commit.message | split(pat="\n") | first | trim }}\
-    {% if commit.github.username %} by @{{ commit.github.username }}{%- endif %}\
-    {% if commit.github.pr_number %} in #{{ commit.github.pr_number }}{%- endif %}
+    {% if commit.remote.username %} by @{{ commit.remote.username }}{%- endif %}\
+    {% if commit.remote.pr_number %} in #{{ commit.remote.pr_number }}{%- endif %}
 {%- endfor -%}
 ```
 
diff --git a/website/docs/integration/gitlab.md b/website/docs/integration/gitlab.md
index 375f7b7..1db4f64 100644
--- a/website/docs/integration/gitlab.md
+++ b/website/docs/integration/gitlab.md
@@ -106,7 +106,7 @@ For each commit, GitLab related values are added as a nested object (named `gitl
 
   "...": "<strip>",
 
-  "gitlab": {
+  "remote": {
     "username": "orhun",
     "pr_title": "some things have changed",
     "pr_number": 420,
@@ -121,8 +121,8 @@ This can be used in the template as follows:
 ```
 {% for commit in commits %}
   * {{ commit.message | split(pat="\n") | first | trim }}\
-    {% if commit.gitlab.username %} by @{{ commit.gitlab.username }}{%- endif %}\
-    {% if commit.gitlab.pr_number %} in #{{ commit.gitlab.pr_number }}{%- endif %}
+    {% if commit.remote.username %} by @{{ commit.remote.username }}{%- endif %}\
+    {% if commit.remote.pr_number %} in #{{ commit.remote.pr_number }}{%- endif %}
 {%- endfor -%}
 ```
 
diff --git a/website/docs/tips-and-tricks.md b/website/docs/tips-and-tricks.md
index 693bcc2..59960d0 100644
--- a/website/docs/tips-and-tricks.md
+++ b/website/docs/tips-and-tricks.md
@@ -65,7 +65,7 @@ commit_parsers = [
 ## Skip commits by GitHub PR label
 
 ```jinja2
-{% if commit.github.pr_labels is containing("skip-release-notes") %}
+{% if commit.remote.pr_labels is containing("skip-release-notes") %}
     {% continue %}
 {% endif %}
 ```
diff --git a/website/docs/usage/args.md b/website/docs/usage/args.md
index 6b3f657..425e9e6 100644
--- a/website/docs/usage/args.md
+++ b/website/docs/usage/args.md
@@ -11,16 +11,17 @@ git-cliff [FLAGS] [OPTIONS] [--] [RANGE]
 ## Flags
 
 ```
--h, --help            Prints help information
--V, --version         Prints version information
--v, --verbose...      Increases the logging verbosity
-    --bumped-version  Prints bumped version for unreleased changes
--l, --latest          Processes the commits starting from the latest tag
-    --current         Processes the commits that belong to the current tag
--u, --unreleased      Processes the commits that do not belong to a tag
-    --topo-order      Sorts the tags topologically
-    --no-exec         Disables the external command execution
--x, --context         Prints changelog context as JSON
+-h, --help             Prints help information
+-V, --version          Prints version information
+-v, --verbose...       Increases the logging verbosity
+    --bumped-version   Prints bumped version for unreleased changes
+-l, --latest           Processes the commits starting from the latest tag
+    --current          Processes the commits that belong to the current tag
+-u, --unreleased       Processes the commits that do not belong to a tag
+    --topo-order       Sorts the tags topologically
+    --use-branch-tags  Include only the tags that belong to the current branch
+    --no-exec          Disables the external command execution
+-x, --context          Prints changelog context as JSON
 ```
 
 ## Options
@@ -51,7 +52,7 @@ git-cliff [FLAGS] [OPTIONS] [--] [RANGE]
     --gitlab-token <TOKEN>         Sets the GitLab API token [env: GITLAB_TOKEN]
     --gitlab-repo <OWNER/REPO>     Sets the GitLab repository [env: GITLAB_REPO=]
     --gitea-token <TOKEN>          Sets the Gitea API token [env: GITEA_TOKEN]
-    --gitea-repo <OWNER/REPO>      Sets the GitLab repository [env: GITEA_REPO=]
+    --gitea-repo <OWNER/REPO>      Sets the Gitea repository [env: GITEA_REPO=]
     --bitbucket-token <TOKEN>      Sets the Bitbucket API token [env: BITBUCKET_TOKEN]
     --bitbucket-repo <OWNER/REPO>  Sets the Bitbucket repository [env: BITBUCKET_REPO=]
 ```
diff --git a/website/docs/usage/examples.md b/website/docs/usage/examples.md
index e7b7800..7699c25 100644
--- a/website/docs/usage/examples.md
+++ b/website/docs/usage/examples.md
@@ -15,7 +15,7 @@ git cliff
 Set a tag for the unreleased changes:
 
 ```bash
-# it doesn't have to be an existing tag
+# generates a changelog for the tag '1.0.0' without creating the tag itself
 git cliff --tag 1.0.0
 ```
 
@@ -45,6 +45,12 @@ git cliff v2.2.1..
 git cliff v0.1.0..HEAD
 ```
 
+Only include the tags from the current branch:
+
+```bash
+git cliff --use-branch-tags
+```
+
 Sort the commits inside sections:
 
 ```bash
diff --git a/website/package-lock.json b/website/package-lock.json
index 686c79b..d33abbd 100644
--- a/website/package-lock.json
+++ b/website/package-lock.json
@@ -21,7 +21,7 @@
       "devDependencies": {
         "@docusaurus/module-type-aliases": "^3.4.0",
         "@docusaurus/tsconfig": "^3.5.2",
-        "typescript": "^5.5.4"
+        "typescript": "^5.6.2"
       },
       "engines": {
         "node": ">=18.0"
@@ -14092,9 +14092,9 @@
       }
     },
     "node_modules/typescript": {
-      "version": "5.5.4",
-      "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz",
-      "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==",
+      "version": "5.6.2",
+      "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.2.tgz",
+      "integrity": "sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==",
       "bin": {
         "tsc": "bin/tsc",
         "tsserver": "bin/tsserver"
diff --git a/website/package.json b/website/package.json
index 08f55cd..c895ae9 100644
--- a/website/package.json
+++ b/website/package.json
@@ -28,7 +28,7 @@
   "devDependencies": {
     "@docusaurus/module-type-aliases": "^3.4.0",
     "@docusaurus/tsconfig": "^3.5.2",
-    "typescript": "^5.5.4"
+    "typescript": "^5.6.2"
   },
   "browserslist": {
     "production": [
diff --git a/website/yarn.lock b/website/yarn.lock
index 820c131..f6fa286 100644
--- a/website/yarn.lock
+++ b/website/yarn.lock
@@ -8169,10 +8169,10 @@ typedarray-to-buffer@^3.1.5:
   dependencies:
     is-typedarray "^1.0.0"
 
-typescript@^5.5.4:
-  version "5.5.4"
-  resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.5.4.tgz#d9852d6c82bad2d2eda4fd74a5762a8f5909e9ba"
-  integrity sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==
+typescript@^5.6.2:
+  version "5.6.2"
+  resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.6.2.tgz#d1de67b6bef77c41823f822df8f0b3bcff60a5a0"
+  integrity sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==
 
 undici-types@~5.26.4:
   version "5.26.5"


Test patch:
diff --git a/.github/fixtures/test-bitbucket-integration/cliff.toml b/.github/fixtures/test-bitbucket-integration/cliff.toml
index b3a6c73..9ad05d1 100644
--- a/.github/fixtures/test-bitbucket-integration/cliff.toml
+++ b/.github/fixtures/test-bitbucket-integration/cliff.toml
@@ -10,8 +10,8 @@ body = """
 {%- if version %} in {{ version }}{%- endif -%}
 {% for commit in commits %}
   * {{ commit.message | split(pat="\n") | first | trim }}\
-    {% if commit.bitbucket.username %} by @{{ commit.bitbucket.username }}{%- endif -%}
-    {% if commit.bitbucket.pr_number %} in #{{ commit.bitbucket.pr_number }}{%- endif %}
+    {% if commit.remote.username %} by @{{ commit.remote.username }}{%- endif -%}
+    {% if commit.remote.pr_number %} in #{{ commit.remote.pr_number }}{%- endif %}
 {%- endfor -%}
 
 {% if bitbucket.contributors | filter(attribute="is_first_time", value=true) | length != 0 %}
diff --git a/.github/fixtures/test-gitea-integration/cliff.toml b/.github/fixtures/test-gitea-integration/cliff.toml
index 20c9b4e..00c548f 100644
--- a/.github/fixtures/test-gitea-integration/cliff.toml
+++ b/.github/fixtures/test-gitea-integration/cliff.toml
@@ -10,8 +10,8 @@ body = """
 {%- if version %} in {{ version }}{%- endif -%}
 {% for commit in commits %}
   * {{ commit.message | split(pat="\n") | first | trim }}\
-    {% if commit.gitea.username %} by @{{ commit.gitea.username }}{%- endif -%}
-    {% if commit.gitea.pr_number %} in #{{ commit.gitea.pr_number }}{%- endif %}
+    {% if commit.remote.username %} by @{{ commit.remote.username }}{%- endif -%}
+    {% if commit.remote.pr_number %} in #{{ commit.remote.pr_number }}{%- endif %}
 {%- endfor -%}
 
 {% if gitea.contributors | filter(attribute="is_first_time", value=true) | length != 0 %}
diff --git a/.github/fixtures/test-github-integration/cliff.toml b/.github/fixtures/test-github-integration/cliff.toml
index 17adc95..0bb109c 100644
--- a/.github/fixtures/test-github-integration/cliff.toml
+++ b/.github/fixtures/test-github-integration/cliff.toml
@@ -11,8 +11,8 @@ body = """
 {%- if version %} in {{ version }}{%- endif -%}
 {% for commit in commits %}
   * {{ commit.message | split(pat="\n") | first | trim }}\
-    {% if commit.github.username %} by @{{ commit.github.username }}{%- endif -%}
-    {% if commit.github.pr_number %} in #{{ commit.github.pr_number }}{%- endif %}
+    {% if commit.remote.username %} by @{{ commit.remote.username }}{%- endif -%}
+    {% if commit.remote.pr_number %} in #{{ commit.remote.pr_number }}{%- endif %}
 {%- endfor -%}
 
 {% if github.contributors | filter(attribute="is_first_time", value=true) | length != 0 %}
diff --git a/.github/fixtures/test-gitlab-integration/cliff.toml b/.github/fixtures/test-gitlab-integration/cliff.toml
index 70d8355..2490a37 100644
--- a/.github/fixtures/test-gitlab-integration/cliff.toml
+++ b/.github/fixtures/test-gitlab-integration/cliff.toml
@@ -11,8 +11,8 @@ body = """
 {%- if version %} in {{ version }}{%- endif -%}
 {% for commit in commits %}
   * {{ commit.message | split(pat="\n") | first | trim }}\
-    {% if commit.gitlab.username %} by @{{ commit.gitlab.username }}{%- endif -%}
-    {% if commit.gitlab.pr_number %} in #{{ commit.gitlab.pr_number }}{%- endif %}
+    {% if commit.remote.username %} by @{{ commit.remote.username }}{%- endif -%}
+    {% if commit.remote.pr_number %} in #{{ commit.remote.pr_number }}{%- endif %}
 {%- endfor -%}
 
 {% if gitlab.contributors | filter(attribute="is_first_time", value=true) | length != 0 %}
diff --git a/git-cliff-core/tests/integration_test.rs b/git-cliff-core/tests/integration_test.rs
index 58141a9..45add26 100644
--- a/git-cliff-core/tests/integration_test.rs
+++ b/git-cliff-core/tests/integration_test.rs
@@ -119,6 +119,7 @@ fn generate_changelog() -> Result<()> {
 		skip_tags:                None,
 		ignore_tags:              None,
 		count_tags:               None,
+		use_branch_tags:          None,
 		topo_order:               None,
 		sort_commits:             None,
 		link_parsers:             Some(vec![
@@ -260,7 +261,7 @@ fn generate_changelog() -> Result<()> {
 	];
 
 	let out = &mut String::new();
-	let template = Template::new(changelog_config.body.unwrap(), false)?;
+	let template = Template::new("test", changelog_config.body.unwrap(), false)?;
 
 	writeln!(out, "{}", changelog_config.header.unwrap()).unwrap();
 	for release in releases {