Skip to content
Skillv1.0.0

conventional-commit-message

Generate high-quality Conventional Commit messages for repositories using conventional-changelog-conventionalcommits.

by conventional-changelog(0) 0 installs
Free
Sign in to install

Free account. Installing gives you the manifest plus copy-paste snippets.

See reviews

About

Imported from conventional-changelog/conventional-changelog (skills/conventional-commit-message/SKILL.md) via skills.sh. Install upstream with npx skills add conventional-changelog/conventional-changelog --skill conventional-commit-message. Copyright stays with the author (MIT).

Conventional Commit Message

Use this skill when writing, amending, reviewing, or suggesting commit messages for repositories that use the conventional-changelog-conventionalcommits preset or compatible Conventional Commits release tooling.

Commit Shape

Use the Conventional Commits 1.0.0 message structure:

<type>[optional scope][optional !]: <description>

[optional body]

[optional footer(s)]

Rules:

  • type is required and is followed by an optional parenthesized scope, an optional !, and : .
  • description is required immediately after : . Keep it concise, changelog-ready, and lower-case unless a proper noun or identifier requires casing. Do not end it with a period.
  • scope is optional and should name a section of the codebase.
  • A longer body is optional, starts one blank line after the description, and is free-form.
  • Footers are optional, start one blank line after the body or description, and each use either Token: value or Token #value.
  • Footer tokens use hyphens instead of spaces, such as Reviewed-by, except for BREAKING CHANGE. BREAKING-CHANGE is synonymous with BREAKING CHANGE.
  • Footer values may contain spaces and newlines. A footer value ends when the next valid footer token and separator is observed.
  • Conventional Commit units are not case-sensitive, except BREAKING CHANGE, which must be uppercase when used as that footer token.
  • Prefer one commit per coherent change. If one diff contains unrelated release visible changes, recommend splitting it.
  • Write the description so it reads well as a bullet in a generated changelog. Avoid vague implementation notes like add some feature, update stuff, or fix issue. Prefer user-facing outcomes such as support custom scopes, preserve prerelease tags, or require Node.js 22.
  • Wrap code identifiers in the description in backticks — function, option, flag, type, or file names: add `autocase` to match camelCase and kebab-case forms, support `--no-*` negation. GitHub renders backticks in commit messages and generated changelogs preserve them, and they mark words like flag or rest as code where plain prose would be ambiguous.
  • Wrap any @-prefixed token that is not an intentional GitHub user mention in backticks — scoped package names (@types/node), decorators (@Injectable), JSDoc/annotation tags (@deprecated). GitHub parses a bare @name in commit messages and changelogs as a user mention, which can link and notify an unrelated GitHub account.
  • Active verb phrases are usually better than passive sentences. Prefer support custom scopes over custom scopes were added unless passive voice is clearly more natural for the project.

Breaking changes are indicated by ! immediately before : in the header or by a breaking-change footer. Use the footer when the impact is known:

feat(parser)!: remove legacy token fallback

BREAKING CHANGE: custom token fallbacks are no longer applied during parsing.

If ! is used and no breaking-change footer is provided, the description is used to describe the breaking change.

Type Selection

Default visible types:

  • feat: user-facing feature; appears under Features; bumps minor. Use this when a commit adds a new feature.
  • feature: accepted alias for feat; prefer feat unless matching existing project style.
  • fix: bug fix or correctness fix; appears under Bug Fixes; bumps patch. Use this when a commit represents a bug fix.
  • perf: performance improvement; appears under Performance Improvements; bumps patch.
  • revert: revert commit; appears under Reverts; bumps patch.

Default hidden types:

  • docs: documentation-only change.
  • style: formatting, whitespace, punctuation, or style-only change with no behavior change.
  • chore: general maintenance that should not be in changelog and should not bump, used only when no more specific hidden type fits.
  • refactor: code change that intentionally preserves behavior/API.
  • test: tests only.
  • build: build system, packaging, dependency metadata, generated build setup.
  • ci: CI workflow or automation-only change.

Treat hidden types as no-changelog and no-bump intent. If a code change clearly must not affect released behavior or API, use a hidden type instead of fix or feat, even when source files changed.

Types other than feat and fix are allowed by the Conventional Commits specification, but the spec gives them no implicit SemVer effect unless they include a breaking-change marker. This repository's preset assigns additional visibility and bump behavior through its configured commit types.

Do not use chore as a catch-all for every hidden change. Prefer the hidden type that describes the change most precisely: build for package manager, build tooling, dependency metadata, generated build setup, and workspace configuration; ci for CI-only automation; test for tests; docs for documentation; refactor for behavior-preserving code restructuring; and style for formatting-only changes.

Do not add !, BREAKING CHANGE, or Release-As to a hidden commit unless the release impact is intentional. Those signals override the hidden/no-bump intent.

Before choosing a hidden type, first ask whether the diff changes the public contract of any published package, even if the changed files are metadata, configuration, tests, generated files, or CI. Public contract includes supported runtime and platform versions, package exports, CLI behavior, config presets, peer dependency requirements, generated output, documented APIs, and default behavior. If the public contract becomes stricter, removes previously supported usage, or changes user-visible behavior, use a visible type. If previously supported usage no longer works, use ! and a BREAKING CHANGE footer.

Common red flags for release-visible or breaking impact:

  • Raising minimum runtime, platform, browser, or engine support.
  • Removing, renaming, or narrowing package exports, entry points, CLI flags, options, config presets, or documented APIs.
  • Tightening peer dependency ranges or required external tools.
  • Changing generated output, defaults, validation rules, parsing behavior, or lint/config rules that consumers receive.

Impact Heuristics

Choose the type by release impact, not by file path:

  • Public behavior added: feat.
  • Public behavior corrected: fix.
  • Runtime speed/memory improvement without behavior change: perf.
  • Runtime dependency updates in dependencies: fix. They change the published package dependency graph, can improve correctness/security/runtime behavior, and should trigger a release even when source code is untouched. Use ! only if the dependency update changes or removes supported public behavior.
  • Public contract made stricter or previously supported usage removed: feat! or fix! with a BREAKING CHANGE footer. Example: raising engines.node to Node.js 22 should use a subject like require Node.js 22.
  • Internal rewrite with preserved behavior: refactor.
  • Dependency lockfile/package-manager maintenance, build tooling, generated build setup, or workspace package-manager configuration with no shipped behavior change: build, unless local style strongly prefers another hidden type.
  • CI-only workflow edits: ci.
  • Tests added or adjusted without product code impact: test.
  • Docs/readme/examples prose only: docs.
  • General housekeeping that does not fit the more specific hidden types: chore.

When unsure whether a source-code change is user-visible, inspect tests and public API usage. If the change is defensive cleanup, migration plumbing, renaming private helpers, lint fixes, or type-only restructuring, prefer a hidden type.

Scope Selection

Before choosing a scope, inspect the repository:

git diff --staged --name-only
git diff --name-only
rg --files -g '*commitlint*' -g '.commitlintrc*' -g 'commitlint.config.*'
rg --files -g 'package.json'

Use staged changes first. If nothing is staged, use the working tree diff.

If the project uses commitlint, read its config before choosing a message. The config may define allowed types, allowed scopes, required casing, max lengths, and other local formatting rules. Common locations include .commitlintrc, .commitlintrc.json, .commitlintrc.yaml, .commitlintrc.yml, .commitlintrc.js, .commitlintrc.cjs, .commitlintrc.mjs, .commitlintrc.ts, commitlint.config.js, commitlint.config.cjs, commitlint.config.mjs, and commitlint.config.ts.

Single-repo projects:

  • Usually omit the scope.
  • Use a scope only when the project already has clear scopes such as cli, docs, deps, release, or subsystem names.

Monorepos:

  • Prefer the affected package name as scope.
  • Derive package scopes from workspace package names, existing commitlint scope-enum, or recent commits.
  • If commitlint or local tooling supports multiple scopes and one coherent release-visible change affects several published packages, use all affected package scopes instead of collapsing the change to one package.
  • Prefer the repository's accepted multiple-scope separator. If local config enables multiple scopes but does not make the separator obvious, validate a comma-separated scope list with commitlint before using it.
  • If package names are npm-scoped, follow the repo's existing convention: either the full package name or the unscoped package segment.
  • If one package changed, use that package scope.
  • If several packages changed for one shared reason, use a shared scope such as deps, dev-deps, or release when that scope adds useful meaning.
  • For monorepo-wide release-impacting changes that touch many packages, prefer omitting the scope unless the repo requires one. Release tooling usually uses the changed packages, not a global scope, to decide which packages are affected.
  • If several packages changed for different reasons, first try to describe the common intent honestly. If the only honest message would be vague or hide release impact, then suggest separate commits.

For dependency-only work:

  • Use fix(deps) for runtime dependency updates in dependencies when deps is an accepted scope.
  • Use dev-deps for development-only tooling dependency updates when that is an accepted scope.

Message Construction Workflow

  1. Inspect changed files and diff summary.
  2. Identify the released behavior impact.
  3. Choose visible vs hidden type.
  4. Choose the narrowest valid scope.
  5. Write the subject as a changelog bullet from the user's perspective when visible, or from the maintenance intent when hidden.
  6. Add body/footer only when needed for breaking changes, issue closure, release-as, or important context.
  7. If the work is explicitly tied to an issue, PR, bug report, or user-provided tracker URL, include the relevant reference in the commit body/footer. For fixes that should close the issue, use a closing footer such as Fixes #123.. For non-closing context, use a non-closing reference such as Refs #123..
  8. If commitlint is configured and the CLI is available, validate the candidate before presenting it to the user.

Validate with the local installed commitlint binary first when possible. Prefer ./node_modules/.bin/commitlint over package-manager runners because it avoids package manager environment, sandbox, and registry behavior while still using the repository's installed version and config.

echo 'type(scope): subject' | ./node_modules/.bin/commitlint

Use package-manager runners only as fallback when the local binary is missing and running them is acceptable in the current environment:

echo 'type(scope): subject' | pnpm commitlint
echo 'type(scope): subject' | npm exec commitlint
echo 'type(scope): subject' | npx commitlint

Use the actual candidate message in place of the example. For multi-line messages, use printf or another command that preserves the full message exactly:

printf '%s\n\n%s\n' 'feat(parser)!: remove legacy token fallback' 'BREAKING CHANGE: custom token fallbacks are no longer applied.' | ./node_modules/.bin/commitlint

If commitlint fails, adjust the type, scope, case, or subject length and validate again. If commitlint is configured but the CLI cannot be run in the current environment, tell the user.

Use issue references naturally:

fix(parser): handle empty commit body refs #123

Use closing keywords only when the commit should close an issue:

fix(cli): preserve prerelease tag when appending changelog

Fixes #123.

For coherent changes affecting multiple packages in a monorepo, use multiple scopes when supported by the repository:

fix(package-a,package-b): preserve compare links

Fixes #123.

Examples

Visible release entries:

feat(writer): support scoped package links
feat!: require Node.js 22
feat: add `rest` function to read all remaining arguments
fix(parser): keep issue references from multiline footers
fix(cli): handle `--no-*` flags in strict mode
perf(git-client): avoid duplicate tag lookups
revert: feat(writer): support scoped package links

Hidden no-bump entries:

refactor(conventional-changelog): simplify context defaults
test(writer): cover empty reference groups
docs(conventionalcommits): clarify hidden commit types
build(dev-deps): update oxlint
ci: use node 22 in tests
chore(release): prepare package metadata

Monorepo package scopes:

fix(conventional-changelog-writer): preserve reference order
refactor(conventional-commits-parser): split token normalization
test(git-client): cover lightweight tags

Output Style

When the user asks for a commit message, output only the recommended message unless they ask for explanation or alternatives. For uncertain impact, provide two concise options and explain the release consequence:

fix(parser): handle empty commit body

or, if no release bump is intended:

refactor(parser): handle empty commit body defensively

Use it

Copy one of these into your project. Installing also returns the manifest and these snippets.

yaml
targets:
  - https://api.opensmartroute.ai/api/v1/registry/conventional-changelog-conventional-changelog-convention-c14683/manifest   # or paste the manifest below

Manifest

An Open Capability Manifest: the router reads it to know what this does, what it costs and when to pick it.

conventional-changelog-conventional-changelog-convention-c14683.ocm.jsonjson
{
  "ocm": "1",
  "id": "conventional-changelog-conventional-changelog-convention-c14683",
  "kind": "skill",
  "name": "conventional-commit-message",
  "description": "Generate high-quality Conventional Commit messages for repositories using conventional-changelog-conventionalcommits.",
  "publisher": "conventional-changelog",
  "version": "1.0.0",
  "capabilities": {
    "domains": [
      "general"
    ],
    "tags": [
      "skill-md",
      "conventional-commits",
      "conventional-changelog",
      "commit-message",
      "changelog",
      "release",
      "monorepo",
      "skills-sh"
    ],
    "languages": [
      "en"
    ]
  },
  "quality_prior": 0.6,
  "examples": [
    "Generate high-quality Conventional Commit messages for repositories using conventional-changelog-conventionalcommits."
  ],
  "primary": false,
  "metadata": {
    "source": {
      "provider": "skills.sh",
      "repository": "https://github.com/conventional-changelog/conventional-changelog",
      "path": "skills/conventional-commit-message/SKILL.md",
      "ref": "HEAD",
      "url": "https://www.skills.sh/conventional-changelog/conventional-changelog/conventional-commit-message",
      "key": "conventional-changelog/conventional-changelog/skills/conventional-commit-message/SKILL.md"
    },
    "compatibility": "['Claude Code', 'Codex', 'Cursor', 'Gemini CLI', 'GitHub Copilot', 'Windsurf', 'Cline', 'Roo Code', 'Goose', 'Continue', 'OpenCode', 'Amp', 'universal']",
    "license": "MIT"
  },
  "instructions": "# Conventional Commit Message\n\nUse this skill when writing, amending, reviewing, or suggesting commit messages for repositories that use the `conventional-changelog-conventionalcommits` preset or compatible Conventional Commits release tooling.\n\n## Commit Shape\n\nUse the Conventional Commits 1.0.0 message structure:\n\n```text\n<type>[optional scope][optional !]: <description>\n\n[optional body]\n\n[optional footer(s)]\n```\n\nRules:\n\n- `type` is required and is followed by an optional parenthesized `scope`, an optional `!`, and `: `.\n- `description` is required immediately after `: `. Keep it concise, c",
  "cost": {
    "context_tokens": 3511
  }
}

Fetch it by URL: GET /api/v1/registry/conventional-changelog-conventional-changelog-convention-c14683/manifest?version=1.0.0

Reviews

Star ratings from people who tried it. One review per account; edit yours any time.

No reviews yet. Install it, try it, and be the first to rate it.