@hyperfrontend/versioning/commits

commits/

Conventional commit parsing and models.

Overview

Parsing and models for the Conventional Commits specification. Uses state-machine tokenization for predictable O(n) performance.

Usage Examples

Parsing Commits

import { parseConventionalCommit, isConventionalCommit } from '@hyperfrontend/versioning'

// Parse a commit message
const commit = parseConventionalCommit('feat(api): add user endpoint')
console.log(commit.type) // 'feat'
console.log(commit.scope) // ['api']
console.log(commit.subject) // 'add user endpoint'

// Multi-scope headers produce multi-element arrays
const multi = parseConventionalCommit('feat(versioning,questions): add filter')
console.log(multi.scope) // ['versioning', 'questions']

// Scopeless commits produce an empty array
const scopeless = parseConventionalCommit('docs: update README')
console.log(scopeless.scope) // []

// Check format before parsing
if (isConventionalCommit(message)) {
  const parsed = parseConventionalCommit(message)
}

Breaking Changes

import { parseConventionalCommit } from '@hyperfrontend/versioning'

// Breaking change via !
const breaking1 = parseConventionalCommit('feat!: remove deprecated API')
console.log(breaking1.breaking) // true

// Breaking change via footer
const breaking2 = parseConventionalCommit(`fix: update signature

BREAKING CHANGE: The return type is now a Promise`)
console.log(breaking2.breaking) // true
console.log(breaking2.breakingDescription) // 'The return type is now a Promise'

Body and Footers

import { parseConventionalCommit } from '@hyperfrontend/versioning'

const commit = parseConventionalCommit(`feat(core): add validation

This adds input validation to all public methods.
Invalid inputs now throw descriptive errors.

Refs: ABC-123
Closes #456`)

console.log(commit.body)
// 'This adds input validation to all public methods.\nInvalid inputs now throw descriptive errors.'

console.log(commit.footers)
// [
//   { key: 'Refs', value: 'ABC-123', separator: ':' },
//   { key: 'Closes', value: '456', separator: ' #' }
// ]

Creating Commits

import { createConventionalCommit, createCommitFooter } from '@hyperfrontend/versioning'

const commit = createConventionalCommit('feat', 'add feature', {
  scope: ['api'],
  body: 'Detailed description',
  footers: [createCommitFooter('Refs', 'ABC-123'), createCommitFooter('Closes', '456', ' #')],
  breaking: true,
})

console.log(commit.raw)
// 'feat(api)!: add feature\n\nDetailed description\n\nRefs: ABC-123\nCloses #456'

// Multi-scope headers
const multi = createConventionalCommit('feat', 'shared change', { scope: ['versioning', 'questions'] })
console.log(multi.raw) // 'feat(versioning,questions): shared change'

Semver Integration

import { parseConventionalCommit, getSemverBump } from '@hyperfrontend/versioning'

const commit = parseConventionalCommit('feat: add feature')
const bump = getSemverBump(commit.type, commit.breaking)
console.log(bump) // 'minor'

const breaking = parseConventionalCommit('fix!: change API')
const breakingBump = getSemverBump(breaking.type, breaking.breaking)
console.log(breakingBump) // 'major'

Conventional Commits Format

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

[optional body]

[optional footer(s)]

Header

  • type: Describes the category of change (feat, fix, docs, etc.)
  • scope: Optional context in parentheses. Supports multi-scope headers such as feat(versioning,questions): ...; parsed into a readonly string[] (empty when no scope is present).
  • !: Optional breaking change indicator
  • description: Short summary of the change

Body

Free-form text separated from header by a blank line. Can span multiple paragraphs.

Footers

Token-based trailers in key: value or key #value format:

Refs: ABC-123
Fixes #456
BREAKING CHANGE: API signature changed

Security

  • No regex: All parsing uses character-by-character iteration
  • Input limits: 10KB maximum message length enforced
  • ReDoS safe: No regular expressions means no catastrophic backtracking

See Also

  • classify/: Commit classification for changelog attribution
  • changelog/: Generates entries from commits
  • flow/: Analyzes commits to determine version bumps
  • semver/: Version bumping based on commit types
  • Main README: Package overview and quick start
  • ARCHITECTURE.md: Design principles and data flow

API Reference§

ƒ Functions

§function

allOf(...matchers: unknown): InfrastructureMatcher

Combines matchers with AND logic - returns true if ALL matchers match.
Parameters
NameTypeDescription
§...matchers
unknownMatchers to combine
Returns
InfrastructureMatcher
Combined matcher
Example
Combining matchers with AND logic
const combined = allOf(
  scopeMatcher(['deps']),
  messageMatcher(['security'])
)
§function

anyOf(...matchers: unknown): InfrastructureMatcher

Combines matchers with OR logic - returns true if ANY matcher matches.
Parameters
NameTypeDescription
§...matchers
unknownMatchers to combine
Returns
InfrastructureMatcher
Combined matcher
Example
Combining matchers with OR logic
const combined = anyOf(
  scopeMatcher(['ci', 'build']),
  messageMatcher(['[infra]']),
  custom((ctx) => ctx.scope.some((s) => s.startsWith('tool-')))
)
§function

buildInfrastructureMatcher(config: InfrastructureConfig): InfrastructureMatcher

Builds a combined matcher from infrastructure configuration.
Combines scope-based matching with any custom matcher using OR logic. Path-based matching is handled separately via git queries.
Parameters
NameTypeDescription
§config
InfrastructureConfigInfrastructure configuration
Returns
InfrastructureMatcher
Combined matcher, or null if no matchers configured
Example
Building an infrastructure matcher
const matcher = buildInfrastructureMatcher({
  scopes: ['ci', 'build'],
  matcher: (ctx) => ctx.scope.some((s) => s.startsWith('tool-'))
})
§function

classifyCommit(input: CommitWithRaw, context: ClassificationContext): ClassifiedCommit

Classifies a single commit against a project.
Implements the hybrid classification strategy:
  1. Check scope match (fast path)
  2. Check file touch (validation/catch-all)
  3. Check dependency touch (indirect)
  4. Fallback to excluded
Parameters
NameTypeDescription
§input
CommitWithRawThe commit to classify
§context
ClassificationContextClassification context with project info
Returns
ClassifiedCommit
Classified commit with source attribution
Example
Classifying a single commit
const classified = classifyCommit(
  { commit: parsedCommit, raw: gitCommit },
  { projectScopes: ['versioning'], fileCommitHashes: new Set(['abc123']) }
)
§function

classifyCommits(commits: unknown, context: ClassificationContext): ClassificationResult

Classifies multiple commits against a project.
Parameters
NameTypeDescription
§commits
unknownArray of commits to classify
§context
ClassificationContextClassification context with project info
Returns
ClassificationResult
Classification result with all commits and summary
Example

Classifying multiple commits

const commits = [{ commit: parsedCommit, raw: gitCommit }]
const context = createClassificationContext(['auth'], fileHashes)
const result = classifyCommits(commits, context)
// => { commits: [...], included: [...], excluded: [...], summary: { total: 1, ... } }
§function

createClassificationContext(projectScopes: unknown, fileCommitHashes: ReadonlySet<string>, options?: ClassificationContextOptions): ClassificationContext

Creates a classification context from common inputs.
Parameters
NameTypeDescription
§projectScopes
unknownScopes that match the project
§fileCommitHashes
ReadonlySet<string>Set of commit hashes that touched project files
§options?
ClassificationContextOptionsAdditional context options
Returns
ClassificationContext
A ClassificationContext object
Example

Creating a classification context

const context = createClassificationContext(
  ['auth', 'lib-auth'],
  new Set(['abc123', 'def456']),
  { excludeScopes: ['release'] }
)
§function

createClassifiedCommit(commit: ConventionalCommit, raw: GitCommit, source: CommitSource, options?: CreateClassifiedCommitOptions): ClassifiedCommit

Creates a classified commit.
Parameters
NameTypeDescription
§commit
ConventionalCommitThe parsed conventional commit
§raw
GitCommitThe raw git commit
§source
CommitSourceHow the commit relates to the project
§options?
CreateClassifiedCommitOptionsAdditional classification options
Returns
ClassifiedCommit
A new ClassifiedCommit object
Example

Creating a classified commit

const commit = { type: 'feat', subject: 'add feature', footers: [], breaking: false, raw: '...' }
const raw = { hash: 'abc123', subject: 'feat: add feature', message: '...' }
const classified = createClassifiedCommit(commit, raw, 'direct-scope')
// => { commit, raw, source: 'direct-scope', include: true, preserveScope: false, ... }
§function

createEmptyClassificationSummary(): ClassificationSummary

Creates an empty classification summary.
Returns
ClassificationSummary
A new ClassificationSummary with all counts at zero
Example

Creating an empty classification summary

const summary = createEmptyClassificationSummary()
// => { total: 0, included: 0, excluded: 0, bySource: { 'direct-scope': 0, ... } }
§function

createMatchContext(commit: GitCommit, scope?: unknown): InfrastructureMatchContext

Creates match context from a git commit.
Extracts scope from conventional commit message if present.
Parameters
NameTypeDescription
§commit
GitCommitGit commit to create context for
§scope?
unknownPre-parsed scope array (optional, saves re-parsing)
Returns
InfrastructureMatchContext
Match context for use with matchers
Example

Creating match context from a git commit

const commit = { hash: 'abc123', subject: 'chore(ci): update workflow', message: 'chore(ci): update workflow' }
createMatchContext(commit, ['ci'])
// => { commit, scope: ['ci'], subject: 'chore(ci): update workflow', message: 'chore(ci): update workflow' }
§function

deriveProjectScopes(options: DeriveProjectScopesOptions): unknown

Derives all scope variations that should match a project.
Given a project named 'lib-versioning' with package '@hyperfrontend/versioning', this generates variations like:
  • 'lib-versioning' (full project name)
  • 'versioning' (without lib- prefix)
Parameters
NameTypeDescription
§options
DeriveProjectScopesOptionsProject identification options
Returns
unknown
Array of scope strings that match this project
Examples
Deriving scopes for a library project
deriveProjectScopes({ projectName: 'lib-versioning', packageName: '@hyperfrontend/versioning' })
// Returns: ['lib-versioning', 'versioning']
Deriving scopes for an app project
deriveProjectScopes({ projectName: 'app-demo', packageName: 'demo-app' })
// Returns: ['app-demo', 'demo']
§function

evaluateInfrastructure(commit: GitCommit, matcher: InfrastructureMatcher, scope?: unknown): boolean

Evaluates a commit against an infrastructure matcher.
Parameters
NameTypeDescription
§commit
GitCommitGit commit to evaluate
§matcher
InfrastructureMatcherMatcher function to apply
§scope?
unknownPre-parsed scope (optional)
Returns
boolean
True if commit matches infrastructure criteria
Example

Evaluating a commit against infrastructure matcher

const commit = { hash: 'abc123', subject: 'chore(ci): update workflow', message: '...' }
const ciMatcher = (ctx) => ctx.scope.includes('ci')
evaluateInfrastructure(commit, ciMatcher, ['ci'])
// => true
§function

extractConventionalCommits(commits: unknown): unknown

Extracts conventional commits from classified commits for changelog generation.
Parameters
NameTypeDescription
§commits
unknownArray of classified commits
Returns
unknown
Array of conventional commits
Example

Extracting conventional commits

const classified = classifyCommits(commits, context)
const conventional = extractConventionalCommits(classified.included)
// => [{ type: 'feat', subject: 'add login', ... }]
§function

filterIncluded(commits: unknown): unknown

Filters an array of classified commits to only included ones.
Parameters
NameTypeDescription
§commits
unknownArray of classified commits
Returns
unknown
Only commits marked for inclusion
Example

Filtering for included commits

const classified = classifyCommits(commits, context)
const included = filterIncluded(classified.commits)
// => [{ commit, raw, source: 'direct-scope', include: true, ... }]
§function

messageMatcher(patterns: unknown): InfrastructureMatcher

Creates a matcher that checks if commit message contains any of the given patterns.
Parameters
NameTypeDescription
§patterns
unknownPatterns to search for in commit message (case-insensitive)
Returns
InfrastructureMatcher
Matcher that returns true if message contains any pattern
Example
Matching message patterns
const matcher = messageMatcher(['[infra]', '[ci skip]'])
Negates a matcher - returns true if matcher returns false.
Parameters
NameTypeDescription
§matcher
InfrastructureMatcherMatcher to negate
Returns
InfrastructureMatcher
Negated matcher
Example
Negating a matcher
const notRelease = not(scopeMatcher(['release']))
§function

scopeIsExcluded(commitScopes: unknown, excludeScopes: unknown): boolean

Checks if all scopes of a commit are in the exclude list.
A commit is excluded only when every scope entry matches an exclude scope. Commits with no scope entries are never considered excluded here.
Parameters
NameTypeDescription
§commitScopes
unknownScopes from a conventional commit
§excludeScopes
unknownArray of scopes to exclude
Returns
boolean
True if every commit scope is in the exclude list
Example

Checking if a scope should be excluded

scopeIsExcluded(['release'], ['release', 'deps'])
// => true

scopeIsExcluded(['auth'], ['release', 'deps'])
// => false

scopeIsExcluded([], ['release'])
// => false

scopeIsExcluded(['release', 'auth'], ['release'])
// => false (not every scope is excluded)
§function

scopeMatcher(scopes: unknown): InfrastructureMatcher

Creates a matcher that checks if any commit scope matches any of the given scopes.
Parameters
NameTypeDescription
§scopes
unknownScopes to match against (case-insensitive)
Returns
InfrastructureMatcher
Matcher that returns true if any scope element matches
Example
Matching against specific scopes
const matcher = scopeMatcher(['ci', 'build', 'tooling'])
matcher({ scope: ['CI'], ... }) // true
matcher({ scope: ['feat'], ... }) // false
matcher({ scope: ['feat', 'ci'], ... }) // true (any element matches)
§function

scopeMatchesProject(commitScopes: unknown, projectScopes: unknown): boolean

Checks if any element of a commit's scope list matches any of the project scopes.
A commit matches the project when any of its scope entries matches a project scope. Empty commit scopes never match.
Parameters
NameTypeDescription
§commitScopes
unknownScopes from a conventional commit
§projectScopes
unknownArray of scopes that match the project
Returns
boolean
True if at least one commit scope matches the project
Example
Matching scope to project
scopeMatchesProject(['versioning'], ['lib-versioning', 'versioning']) // true
scopeMatchesProject(['logging'], ['lib-versioning', 'versioning']) // false
scopeMatchesProject(['versioning', 'questions'], ['lib-questions']) // true
scopeMatchesProject([], ['lib-versioning']) // false
§function

scopePrefixMatcher(prefixes: unknown): InfrastructureMatcher

Creates a matcher that checks if any commit scope starts with any of the given prefixes.
Parameters
NameTypeDescription
§prefixes
unknownScope prefixes to match (case-insensitive)
Returns
InfrastructureMatcher
Matcher that returns true if any scope element starts with any prefix
Example
Matching prefixed scopes
const matcher = scopePrefixMatcher(['tool-', 'infra-'])
matcher({ scope: ['tool-package'], ... }) // true
matcher({ scope: ['lib-utils'], ... }) // false
§function

scopeRegexMatcher(pattern: RegExp): InfrastructureMatcher

Creates a matcher from a regex pattern tested against each scope element.
Parameters
NameTypeDescription
§pattern
RegExpRegex pattern to test against scopes
Returns
InfrastructureMatcher
Matcher that returns true if any scope element matches the regex
Example
Matching with regex pattern
const matcher = scopeRegexMatcher(/^(ci|build|tool)-.+/)
§function

toChangelogCommit(classified: ClassifiedCommit): ConventionalCommit

Creates a modified conventional commit with scope handling based on classification.
For direct commits, the scope is removed (redundant in project changelog). For indirect commits, the scope is preserved (provides context).
Parameters
NameTypeDescription
§classified
ClassifiedCommitCommit with classification metadata determining scope display
Returns
ConventionalCommit
A conventional commit with appropriate scope handling
Example

Converting classified commit for changelog

const classified = { commit: { type: 'feat', scope: ['auth'], subject: 'add login', ... }, source: 'direct-scope', preserveScope: false, ... }
toChangelogCommit(classified)
// => { type: 'feat', scope: [], subject: 'add login', ... }
§function

cancelled(error?: Error): StepResult

Helper for building a cancelled result with an optional error.
Parameters
NameTypeDescription
§error?
ErrorCause of cancellation attached to the result (omit when the user aborted cleanly)
Returns
StepResult
Step result that stops the session
Example

Cancelling after an executor throws

try { await executor() } catch (err) { return cancelled(err as Error) }
§function

countHeaderLength(draft: CommitDraft, subject: string): number

Computes the character length of the final header including the type(scope)!: prefix and the supplied subject. Powers the live 72-character countdown shown during the subject prompt.
The subject is passed separately (not read from draft.subject) because the caller typically has not yet committed the in-flight input to the draft.
Parameters
NameTypeDescription
§draft
CommitDraftDraft supplying type, scope, and breaking marker
§subject
stringSubject text being typed
Returns
number
Character length the final header will occupy
Example

Counting a header mid-type

countHeaderLength({ type: 'feat', scope: ['core'] }, 'add login')
// => 'feat(core): add login'.length === 21
§function

createAuthorSession(options: CreateAuthorSessionOptions): AuthorSession

Prepares an authoring session without executing it. The returned object carries a resolved config (defaults filled in) and the effective step list, allowing bin wrappers to introspect before running.
Parameters
NameTypeDescription
§options
CreateAuthorSessionOptionsOptional overrides for steps and partial config(default: {})
Returns
AuthorSession
Session description consumable by runAuthorSession
Examples

Using the conventional preset and default config

const session = createAuthorSession()
await runAuthorSession(session)

Overriding only the validate ruleset

createAuthorSession({ config: { validateRuleset: customRuleset } })
§function

createBreakingFromFooter(description: string): BreakingChange

Creates a breaking change from a footer.
Parameters
NameTypeDescription
§description
stringThe description of the breaking change
Returns
BreakingChange
A BreakingChange object with source 'footer'
Example

Creating a breaking change from footer

createBreakingFromFooter('The config format has changed')
// => { isBreaking: true, description: 'The config format has changed', source: 'footer' }
§function

createBreakingFromSubject(description?: string): BreakingChange

Creates a breaking change from a subject indicator (!).
Parameters
NameTypeDescription
§description?
stringOptional description of the breaking change
Returns
BreakingChange
A BreakingChange object with source 'subject'
Example

Creating a breaking change from subject

createBreakingFromSubject('remove deprecated API')
// => { isBreaking: true, description: 'remove deprecated API', source: 'subject' }
§function

createCommitFooter(key: string, value: string, separator: ":" | " #"): CommitFooter

Creates a commit footer.
Parameters
NameTypeDescription
§key
stringFooter identifier such as 'Refs', 'Fixes', or 'BREAKING CHANGE'
§value
stringAssociated content for the footer entry
§separator
":" | " #"Delimiter between key and value (':' or ' #')(default: ':')
Returns
CommitFooter
A new CommitFooter object
Example

Creating commit footers

createCommitFooter('Refs', '#123')
// => { key: 'Refs', value: '#123', separator: ':' }

createCommitFooter('Fixes', '456', ' #')
// => { key: 'Fixes', value: '456', separator: ' #' }
§function

createConventionalCommit(type: string, subject: string, options?: CreateConventionalCommitOptions): ConventionalCommit

Creates a conventional commit.
Parameters
NameTypeDescription
§type
stringThe commit type (e.g., 'feat', 'fix')
§subject
stringThe commit subject line
§options?
CreateConventionalCommitOptionsOptional configuration for scope, body, footers, etc.
Returns
ConventionalCommit
A new ConventionalCommit object
Example

Creating conventional commits

createConventionalCommit('feat', 'add user authentication')
// => { type: 'feat', subject: 'add user authentication', scope: [], footers: [], breaking: false, raw: 'feat: add user authentication' }

createConventionalCommit('fix', 'resolve memory leak', { scope: ['core'], breaking: true })
// => { type: 'fix', subject: 'resolve memory leak', scope: ['core'], breaking: true, ... }

createConventionalCommit('feat', 'add x', { scope: ['versioning', 'questions'] })
// => { ..., scope: ['versioning', 'questions'], raw: 'feat(versioning,questions): add x' }
§function

createNonBreaking(): BreakingChange

Creates a non-breaking change.
Returns
BreakingChange
A BreakingChange object indicating no breaking change
Example

Creating a non-breaking change

createNonBreaking()
// => { isBreaking: false, source: 'none' }
§function

createSessionContext(config: SessionConfig): SessionContext

Creates a fresh session context seeded with an empty draft.
Parameters
NameTypeDescription
§config
SessionConfigResolved session configuration
Returns
SessionContext
Session context ready for the first step
Example

Creating a bare context

createSessionContext(config)
// => { draft: {}, candidateScopes: [], defaultScope: undefined, config }
§function

defaultScope(candidates: unknown): string

Computes the default scope to pre-select in the scope step.
Algorithm (matches locked decision D3):
  1. A single candidate wins outright.
  2. Otherwise, if one candidate's path is a prefix of every other
candidate's path, that nearest common ancestor wins.
  1. Otherwise, there is no default.
Parameters
NameTypeDescription
§candidates
unknownScopes produced by discoverScopes
Returns
string
Scope name to pre-select, or undefined when no default is resolvable
Examples

Single owner wins

defaultScope([{ name: 'alpha', path: '/repo/libs/alpha' }])
// => 'alpha'

Common ancestor wins

defaultScope([
  { name: 'root', path: '/repo' },
  { name: 'alpha', path: '/repo/libs/alpha' },
])
// => 'root'

Disjoint ownership has no default

defaultScope([
  { name: 'alpha', path: '/repo/libs/alpha' },
  { name: 'beta', path: '/repo/libs/beta' },
])
// => undefined
§function

discoverScopes(stagedPaths: unknown, options: DiscoverScopesOptions): unknown

Resolves each staged path to its owning project by walking upward to the nearest project.json / package.json, reads the name field, and returns the unique set as DiscoveredScope entries. Entries inside node_modules or .git are dropped before walking; the caller's scopeFilter is applied after collection.
Parameters
NameTypeDescription
§stagedPaths
unknownPaths emitted by the staged-paths provider (relative or absolute)
§options
DiscoverScopesOptionsFilter + cwd configuration
Returns
unknown
Unique scopes in staging order (first appearance wins)
Example

Discovering scopes for a set of staged files

discoverScopes(['libs/versioning/src/a.ts', 'libs/questions/src/b.ts'], { cwd: '/repo' })
// => [
//   { name: '@hyperfrontend/versioning', path: '/repo/libs/versioning' },
//   { name: '@hyperfrontend/questions', path: '/repo/libs/questions' },
// ]
§function

done(): StepResult

Helper for building a done result.
Returns
StepResult
Step result that advances the runner to the next step
Example

Returning done from a step

async run(): Promise<StepResult> { return done() }
§function

formatCommitMessage(draft: CommitDraft): string

Renders a draft as the final commit message string: the exact text that would be written to .git/COMMIT_EDITMSG. Layout: header, blank line, body, blank line, footers.
If draft.breaking and draft.breakingDescription are set and no BREAKING CHANGE:-family footer is already present, one is synthesized at the top of the footer block so the preview mirrors what a compliant parser will read back.
Parameters
NameTypeDescription
§draft
CommitDraftCommit draft to render
Returns
string
Full commit message string with \n separators
Examples

Header only

formatCommitMessage({ type: 'feat', subject: 'add login' })
// => 'feat: add login'

Multi-scope breaking change with closing footer

formatCommitMessage({
  type: 'feat',
  scope: ['versioning', 'questions'],
  subject: 'add x',
  breaking: true,
  breakingDescription: 'removed Y',
  footers: [{ key: 'Closes', value: '#1', separator: ':' }],
})
// => 'feat(versioning,questions)!: add x\n\nBREAKING CHANGE: removed Y\nCloses: #1'
§function

formatHeader(draft: CommitDraft): string

Builds the header line (type(scope)!: subject) from a draft.
Missing fields render as empty; this is intentional so the header can be displayed incrementally during authoring (e.g. before the subject has been typed). Scopes are comma-joined to match the parser's multi-scope format.
Parameters
NameTypeDescription
§draft
CommitDraftDraft to render (may be partial)
Returns
string
Header line; never contains a newline
Examples

Rendering a complete header

formatHeader({ type: 'feat', scope: ['core'], subject: 'add login' })
// => 'feat(core): add login'

Rendering a multi-scope breaking-change header

formatHeader({ type: 'feat', scope: ['versioning', 'questions'], subject: 'add x', breaking: true })
// => 'feat(versioning,questions)!: add x'

Rendering a partially-built draft mid-session

formatHeader({ type: 'fix' })
// => 'fix: '
§function

getSemverBump(type: string, breaking: boolean): "minor" | "patch" | "none" | "major"

Gets the semver bump level for a commit type. Returns 'none' for types that don't trigger a bump.
Parameters
NameTypeDescription
§type
stringThe commit type
§breaking
booleanWhether this is a breaking change
Returns
"minor" | "patch" | "none" | "major"
The semver bump level ('major', 'minor', 'patch', or 'none')
Example

Determining semver bump level

getSemverBump('feat', false)
// => 'minor'

getSemverBump('fix', true)
// => 'major'

getSemverBump('docs', false)
// => 'none'
§function

getStagedPaths(options: StagedPathsOptions): unknown

Default staged-paths provider. Resolves the repository root via git rev-parse --show-toplevel, reads git diff --cached --name-only -z, and returns each staged path as an absolute path anchored at that root.
Git emits staged paths relative to the repository root no matter which directory the command runs from, so anchoring here keeps downstream project-root discovery correct when the session cwd is a subdirectory.
Parameters
NameTypeDescription
§options
StagedPathsOptionsResolver options (cwd, optional timeout)
Returns
unknown
Absolute staged file paths
Example

Reading the current staging area from a subdirectory

getStagedPaths({ cwd: '/repo/apps/demo' })
// => ['/repo/libs/versioning/src/commits/author/index.ts']
§function

goto(stepId: string): StepResult

Helper for building a goto result pointing at the supplied step id.
Parameters
NameTypeDescription
§stepId
stringTarget step id the runner should jump to
Returns
StepResult
Step result that redirects the runner to the named step
Example

Sending the runner back to the `type` step

return goto('type')
§function

isBreakingFooterKey(key: string): boolean

Checks if a footer key indicates a breaking change.
Parameters
NameTypeDescription
§key
stringThe footer key to check
Returns
boolean
True if the key indicates a breaking change
Example

Checking if a footer key indicates breaking change

isBreakingFooterKey('BREAKING CHANGE')
// => true

isBreakingFooterKey('BREAKING-CHANGE')
// => true

isBreakingFooterKey('Refs')
// => false
§function

isConventionalCommit(message: string): boolean

Checks if a commit message follows conventional commit format.
Parameters
NameTypeDescription
§message
stringThe commit message to check
Returns
boolean
true if the message appears to be a conventional commit
Example

Checking if a message is a conventional commit

isConventionalCommit('feat(auth): add OAuth login')
// => true

isConventionalCommit('WIP: still working on this')
// => false

isConventionalCommit('fix: resolve bug')
// => true
§function

isReleaseType(type: string): boolean

Checks if a commit type triggers a release.
Parameters
NameTypeDescription
§type
stringThe commit type to check
Returns
boolean
True if the type triggers a release
Example

Checking for release-triggering types

isReleaseType('feat')
// => true

isReleaseType('chore')
// => false
§function

isStandardType(type: string): unknown

Checks if a commit type is a standard type.
Parameters
NameTypeDescription
§type
stringThe commit type to check
Returns
unknown
True if the type is a standard conventional commit type
Example

Checking for standard commit types

isStandardType('feat')
// => true

isStandardType('custom')
// => false
§function

loadCommitConfig(options: LoadCommitConfigOptions): Promise<LoadedCommitConfig>

Loads the user's commit config. Resolution:
  1. overridePath wins when set
  2. Otherwise walk upward from cwd looking for one of CONFIG_FILE_NAMES
until a workspace boundary marker (.git, pnpm-workspace.yaml) is hit
  1. Missing config is not an error: config becomes {}
Parameters
NameTypeDescription
§options
LoadCommitConfigOptionsSearch inputs
Returns
Promise<LoadedCommitConfig>
Loaded partial config plus the file it came from (if any)
Example

Auto-discovery from cwd

const { config, sourcePath } = await loadCommitConfig({ cwd: process.cwd() })
§function

normalizeSubject(raw: string): string

Applies subject normalisation rules (decision D10): trim edges and strip a single trailing period.
Parameters
NameTypeDescription
§raw
stringSubject string as entered by the user
Returns
string
Normalized subject
Example

Stripping whitespace and a trailing period

normalizeSubject('  add login flow.  ') // => 'add login flow'
§function

parseBody(lines: string[], startIndex: number): ParsedBody

Parses the body section of a commit message.
The body starts after the first blank line and continues until we encounter a footer (key: value or key #value pattern) or end of message.
Parameters
NameTypeDescription
§lines
string[]All lines of the commit message
§startIndex
numberIndex to start looking for body (after header)
Returns
ParsedBody
Parsed body or undefined if no body
Example

Parsing commit body

const lines = [
  'feat: add login',
  '',
  'Implements OAuth flow.',
  '',
  'Refs: #123'
]
const result = parseBody(lines, 1)
// => { body: 'Implements OAuth flow.', endIndex: 4 }
§function

parseConventionalCommit(message: string): ConventionalCommit

Parses a conventional commit message.
Parameters
NameTypeDescription
§message
stringThe complete commit message
Returns
ConventionalCommit
Parsed ConventionalCommit object
Example

Parsing a complete conventional commit message

parseConventionalCommit('feat(auth): add login\n\nImplements OAuth.\n\nRefs: #123')
// => {
//   type: 'feat',
//   scope: ['auth'],
//   subject: 'add login',
//   body: 'Implements OAuth.',
//   footers: [{ key: 'Refs', value: '#123', separator: ':' }],
//   breaking: false,
//   raw: '...'
// }
§function

parseFooters(lines: string[], startIndex: number): ParsedFooters

Parses the footer section of a commit message.
Parameters
NameTypeDescription
§lines
string[]All lines of the commit message
§startIndex
numberIndex where footers start
Returns
ParsedFooters
Parsed footers
Example

Parsing commit footers

const lines = ['feat: add feature', '', 'Refs: #123', 'Fixes #456']
const result = parseFooters(lines, 2)
// => {
//   footers: [
//     { key: 'Refs', value: '#123', separator: ':' },
//     { key: 'Fixes', value: '456', separator: ' #' }
//   ],
//   breakingDescription: undefined
// }
§function

parseHeader(line: string): ParsedHeader

Parses a conventional commit header line.
Supports comma-separated multi-scope headers such as feat(a,b): x which produce a multi-element scope array. Single-scope headers produce a one-element array, and scopeless headers produce an empty array.
Parameters
NameTypeDescription
§line
stringThe first line of the commit message
Returns
ParsedHeader
Parsed header with type, scope array, subject, and breaking flag
Example

Parsing conventional commit headers

parseHeader('feat(auth): add OAuth login')
// => { type: 'feat', scope: ['auth'], subject: 'add OAuth login', breaking: false }

parseHeader('fix!: critical security patch')
// => { type: 'fix', scope: [], subject: 'critical security patch', breaking: true }

parseHeader('feat(versioning,questions): add searchable select')
// => { type: 'feat', scope: ['versioning', 'questions'], subject: 'add searchable select', breaking: false }
§function

parseReferences(raw: string): unknown

Parses a free-form references string into issue footers. Accepts commas, semicolons, or whitespace between entries; ignores tokens that don't match the keyword #number shape.
Parameters
NameTypeDescription
§raw
stringRaw user input from the issues prompt
Returns
unknown
Footers matching each recognized reference
Example

Parsing a mixed references string

parseReferences('fixes #123, re #456')
// => [
//   { key: 'Fixes', value: '123', separator: ' #' },
//   { key: 'Re', value: '456', separator: ' #' },
// ]
§function

resolveSessionConfig(overrides: PartialSessionConfig): SessionConfig

Overlays a partial config over the built-in defaults, producing a fully populated SessionConfig usable by the runner.
Parameters
NameTypeDescription
§overrides
PartialSessionConfigPartial config supplied by the caller (may be undefined)(default: {})
Returns
SessionConfig
Fully resolved configuration
Example

Resolving with no overrides

resolveSessionConfig()
// => { types: DEFAULT_SESSION_TYPES, scopeOptional: false, ... }
§function

runAuthorSession(session: AuthorSession): Promise<SessionOutcome>

Executes the session step-by-step. Handles goto jumps, surfaces Ctrl-C cancellations as { status: 'cancelled' } outcomes, and (on success) returns the final formatted message alongside the committed status.
Parameters
NameTypeDescription
§session
AuthorSessionSession description produced by createAuthorSession
Returns
Promise<SessionOutcome>
Terminal outcome describing how the session ended
Example

Running a session to completion

const session = createAuthorSession({ config: { skipCommit: true } })
const outcome = await runAuthorSession(session)
// => { status: 'committed', message: 'feat: ...' }
§function

toDraft(commit: ConventionalCommit): CommitDraft

Promotes any ConventionalCommit to a CommitDraft. Useful for editing a parsed commit inside an authoring session.
Parameters
NameTypeDescription
§commit
ConventionalCommitParsed conventional commit
Returns
CommitDraft
A draft carrying the same fields as the commit
Example

Promoting a parsed commit to an editable draft

toDraft(parseConventionalCommit('feat: add login'))
// => { type: 'feat', scope: [], subject: 'add login', footers: [], breaking: false }
§function

typeToChoice(type: SessionType): Choice<string>

Maps a SessionType to a Choice usable by the select prompt.
Parameters
NameTypeDescription
§type
SessionTypeSession type entry to render as a selectable choice
Returns
Choice<string>
Choice with the type name as both label and value, plus an optional hint
Example

Rendering the feat type as a select choice

typeToChoice({ name: 'feat', description: 'A new feature' })
// => { label: 'feat', value: 'feat', hint: 'A new feature' }
§function

validateCommit(commit: ConventionalCommit, ruleset: Ruleset): ValidationResult

Runs every rule configured in the ruleset against a parsed commit and aggregates the resulting warnings and errors.
Rules whose config is 'off' (or absent from the ruleset) are skipped. Unknown rule names in the ruleset are ignored: consumers extend the engine by calling validateCommitWithRules() and supplying additional rules.
Parameters
NameTypeDescription
§commit
ConventionalCommitParsed conventional commit to validate
§ruleset
RulesetConfiguration map from rule name to [level, options?]
Returns
ValidationResult
Aggregated validation result
Example

Validating a commit against a preset ruleset

validateCommit(parseConventionalCommit('feat: add login'), conventionalPreset)
// => { valid: true, warnings: [], errors: [] }
§function

validateCommitMessage(raw: string, ruleset: Ruleset): ValidationResult

Parses a raw commit message and validates the resulting commit against the supplied ruleset. Used by the cl bin and anywhere else validation must start from a string rather than a parsed commit.
Parameters
NameTypeDescription
§raw
stringRaw commit message (as written to .git/COMMIT_EDITMSG)
§ruleset
RulesetConfiguration map from rule name to [level, options?]
Returns
ValidationResult
Aggregated validation result
Example

Validating a raw commit message

validateCommitMessage('feat: add login', conventionalPreset)
// => { valid: true, warnings: [], errors: [] }

validateCommitMessage('feat: added login', conventionalPreset).warnings
// => [{ level: 'warn', ruleName: 'imperative-mood', message: ... }]
§function

validateCommitWithRules(commit: ConventionalCommit, ruleset: Ruleset, rules: Readonly<Record<string, Rule<never>>>): ValidationResult

Variant of validateCommit that accepts a caller-supplied rule registry. Useful for consumers that want to add project-specific rules without forking the built-in set.
Parameters
NameTypeDescription
§commit
ConventionalCommitParsed conventional commit to validate
§ruleset
RulesetConfiguration map from rule name to [level, options?]
§rules
Readonly<Record<string, Rule<never>>>Rule registry keyed by rule name
Returns
ValidationResult
Aggregated validation result
Example

Extending the built-in rules with a custom rule

const customRules = { ...BUILT_IN_RULES, 'no-wip': noWipRule }
validateCommitWithRules(commit, { 'no-wip': ['error'] }, customRules)

◈ Interfaces

§interface

ClassificationContext

Classification context containing project and workspace info.
Properties
§readonly dependencyCommitMap?:ReadonlyMap<string, ReadonlySet<string>>Map of dependency name to set of commit hashes touching that dependency
§readonly excludeScopes?:unknownScopes to always exclude
§readonly fileCommitHashes:ReadonlySet<string>Set of commit hashes that touched project files
§readonly includeScopes?:unknownAdditional scopes to include as direct
§readonly infrastructureCommitHashes?:ReadonlySet<string>Set of commit hashes that touched infrastructure paths. These commits will be classified as 'indirect-infra'.
§readonly projectScopes:unknownScopes that should be considered direct matches
§interface

ClassificationResult

Result of classifying multiple commits.
Properties
§readonly commits:unknownAll classified commits
§readonly excluded:unknownCommits excluded from changelog
§readonly included:unknownCommits to include in changelog
§readonly summary:ClassificationSummarySummary statistics
§interface

ClassificationSummary

Summary statistics from classification.
Properties
§readonly bySource:Readonly<Record<CommitSource, number>>Breakdown by source type
§readonly excluded:numberCommits excluded from changelog
§readonly included:numberCommits included in changelog
§readonly total:numberTotal commits processed
§interface

ClassifiedCommit

A commit with classification metadata for changelog generation.
Contains the original commit data plus attribution information that determines inclusion and presentation in changelogs.
Properties
§readonly commit:ConventionalCommitThe parsed conventional commit
§readonly dependencyPath?:unknownDependency chain if indirect (e.g., ['lib-utils'] for lib-app → lib-utils)
§readonly include:booleanWhether to include this commit in changelog
§readonly preserveScope:booleanWhether to preserve scope in changelog output
§readonly raw:GitCommitThe raw git commit (for hash, date, etc.)
§readonly source:CommitSourceHow this commit relates to the project
§readonly touchedFiles?:unknownFiles in this project touched by the commit (if applicable)
§interface

CommitWithRaw

Input for classification - a parsed commit with its raw git data.
Properties
§readonly commit:ConventionalCommitThe parsed conventional commit
§readonly raw:GitCommitThe raw git commit data
§interface

DeriveProjectScopesOptions

Options for deriving project scopes.
Properties
§readonly additionalScopes?:unknownAdditional scopes to include
§readonly packageName?:stringThe npm package name (e.g., '@hyperfrontend/versioning')
§readonly prefixes?:unknownProject name prefixes to strip for scope matching.
§readonly projectName:stringThe project name (e.g., 'lib-versioning')
§interface

InfrastructureConfig

Configuration for building infrastructure commit sets.
Supports multiple detection methods that can be combined:
  • Path-based: Commits touching specific file paths
  • Scope-based: Commits with specific conventional scopes
  • Custom matcher: User-provided matching logic
Properties
§readonly matcher?:InfrastructureMatcherCustom matcher function for complex logic. Combined with paths/scopes using OR logic.
§readonly paths?:unknownFile/directory paths that indicate infrastructure changes. Used to query git for commits touching these paths.
§readonly scopes?:unknownConventional commit scopes that indicate infrastructure. Matched against parsed commit scope.
§interface

InfrastructureMatchContext

Context provided to infrastructure matchers for decision making.
Contains information about a commit that helps determine whether it should be classified as infrastructure-related.
Properties
§readonly commit:GitCommitThe git commit being evaluated
§readonly message:stringFull commit message
§readonly scope:unknownParsed conventional scopes (empty array when the commit has no scope)
§readonly subject:stringCommit message subject
§interface

AuthorSession

Prepared session ready to be handed to runAuthorSession. Contains the fully resolved config and the ordered step list that will be executed.
Properties
§readonly config:SessionConfigFully resolved session configuration
§readonly steps:unknownOrdered step list the runner will iterate
§interface

BreakingChange

Breaking change information.
Properties
§readonly description?:stringDescription of the breaking change
§readonly isBreaking:booleanWhether this is a breaking change
§readonly source:"none" | "subject" | "footer"Source of the breaking change indicator
§interface

CommitDraft

In-progress version of a ConventionalCommit accumulated field-by-field during an interactive authoring session. Every field is optional so the formatter can render intermediate states (e.g. the header as it exists after only type has been picked).
Properties
§readonly body?:stringFull commit body
§readonly breaking?:booleanWhether this is a breaking change: controls the ! subject marker
§readonly breakingDescription?:stringBreaking change description: surfaces as a BREAKING CHANGE: footer when none is already present
§readonly footers?:unknownFooter trailers: caller may leave out BREAKING CHANGE:; the formatter will synthesize it when needed
§readonly scope?:unknownScopes in parentheses (empty or omitted = no scope)
§readonly subject?:stringSubject line
§readonly type?:stringCommit type (feat, fix, docs, etc.)
§interface

CommitFooter

Footer trailer in a conventional commit message
Properties
§readonly key:stringFooter key (e.g., "BREAKING CHANGE", "Refs", "Fixes")
§readonly separator:":" | " #"Whether key used : or # separator
§readonly value:stringFooter value
§interface

ConventionalCommit

Parsed conventional commit message per https://www.conventionalcommits.org/en/v1.0.0/
Properties
§readonly body?:stringFull commit body
§readonly breaking:booleanWhether this is a breaking change
§readonly breakingDescription?:stringBreaking change description (from footer or subject !)
§readonly footers:unknownParsed footer trailers
§readonly raw:stringOriginal raw message
§readonly scope:unknownScopes in parentheses (empty array when header has no scope)
§readonly subject:stringSubject line (after colon)
§readonly type:stringCommit type (feat, fix, docs, etc.)
§interface

CreateAuthorSessionOptions

Inputs accepted by createAuthorSession: the caller may supply their own step list; anything missing is resolved against the defaults used by the conventional preset.
Properties
§readonly config?:PartialSessionConfigPartial configuration overlaid on the built-in defaults
§readonly steps?:unknownOverride for the step sequence; defaults to conventionalPreset
§interface

DiscoveredScope

Single discovered scope with the project root it came from.
Properties
§readonly name:stringScope identifier (the project's name field)
§readonly path:stringAbsolute path to the owning project root
§interface

DiscoverScopesOptions

Options controlling discoverScopes.
Properties
§readonly cwd:stringWorking directory that staged paths are resolved against
§readonly scopeFilter?:(context: ScopeFilterContext) => booleanOptional caller-provided filter; applied after built-in exclusions
§interface

HeaderMaxLengthOptions

Options for the header-max-length rule.
Properties
§readonly maxLength:numberMaximum allowed header length. Use null to disable the check.
§interface

ImperativeMoodOptions

Options for the imperative-mood rule.
Properties
§readonly wordlist?:Readonly<Record<string, string>>Map of past-tense words (lowercase) to their suggested imperative forms. Overrides DEFAULT_IMPERATIVE_WORDLIST when provided.
§interface

LoadCommitConfigOptions

Inputs accepted by loadCommitConfig.
Properties
§readonly cwd:stringDirectory to start the upward search from
§readonly overridePath?:stringExplicit override path from --config <path>, resolved against cwd when relative
§interface

LoadedCommitConfig

Return shape of loadCommitConfig.
Properties
§readonly config:PartialSessionConfigResolved configuration (empty object when no config was found)
§readonly sourcePath?:stringAbsolute path of the config file that was loaded (undefined when nothing was found)
§interface

ParsedBody

Parsed body section of a commit message.
Properties
§body:stringThe body text (may be multiline)
§endIndex:numberIndex where the body ends (start of footers or end of message)
§interface

ParsedFooters

Parsed footer section of a commit message.
Properties
§breakingDescription?:stringBreaking change description if found
§footers:CommitFooter[]All parsed footers
§interface

ParsedHeader

Parsed conventional commit header components.
Properties
§breaking:booleanWhether this is a breaking change
§scope:unknownScopes from parentheses (empty array when header has no scope)
§subject:stringCommit subject line
§type:stringCommit type (feat, fix, chore, etc.)
§interface

Rule

Pure rule definition. Implementations inspect a ConventionalCommit and return zero or more violation messages. The engine applies severity from the ruleset config and aggregates RuleMessages across all rules.
Properties
§readonly name:stringStable identifier used to key the rule in a Ruleset
§interface

RuleContext

Runtime context passed to a rule invocation.
Properties
§readonly level:RuleLevelEffective severity the engine will apply to any violations
§readonly options?:TOptionsRule-specific options resolved from the ruleset config
§interface

RuleMessage

A single violation reported by the engine, tagged with its effective severity.
Properties
§readonly level:"error" | "warn"Effective severity for this violation
§readonly message:stringHuman-readable description of the violation
§readonly ruleName:stringName of the rule that produced the violation
§interface

ScopeEnumOptions

Options for the scope-enum rule.
Properties
§readonly scopes:unknownAllowed scope identifiers. Empty array disables the check.
§interface

ScopeFilterContext

Signature for the scope filter passed in SessionConfig.scopeFilter.
Properties
§readonly name:stringname field read from project.json (or package.json as fallback)
§readonly path:stringAbsolute path to the discovered project root
§interface

SessionConfig

Fully resolved authoring session configuration. Consumers typically supply a partial shape: the config loader (or createAuthorSession) fills the gaps with defaults before handing the result to the runner.
Properties
§readonly commitExecutor?:CommitExecutorOverrides the default git commit executor
§readonly cwd:stringWorking directory used for git operations and scope discovery
§readonly headerMaxLength:numberMaximum header length used by the subject countdown (null disables)
§readonly imperativeWordlist:Readonly<Record<string, string>>Wordlist used by the imperative-mood rule in inline validation
§readonly input?:ReadStreamOptional stream override passed to every prompt in the session
§readonly output?:WriteStreamOptional stream override passed to every prompt in the session
§readonly scopeFilter?:(context: ScopeFilterContext) => booleanOptional filter applied to discovered scopes; receives { path, name }
§readonly scopeMulti:booleanWhen true, the scope step collects multiple scopes via multiselect
§readonly scopeOptional:booleanWhen true, the scope step may be skipped even if no candidates are found
§readonly skipCommit:booleanWhen true, the final commit step is a no-op (session returns the message only)
§readonly stagedPathsProvider:StagedPathsProviderResolver for the staged file list; defaults to git diff --cached --name-only -z
§readonly types:unknownCommit type enum shown in the type step
§readonly validateRuleset:RulesetValidation ruleset used for inline and preview-time warnings
§interface

SessionContext

Mutable container threaded through every step. The draft field accumulates the in-progress commit message; candidateScopes/defaultScope are filled by the resolve-scope step and consumed by later steps. config is the fully resolved SessionConfig shared across the session.
Properties
§candidateScopes:unknownScopes discovered from the staged file set (may be empty)
§readonly config:SessionConfigResolved configuration for the session
§defaultScope:stringDefault scope pre-selected by the scope step (undefined = no default)
§draft:CommitDraftIn-progress commit draft accumulated as steps execute
§interface

SessionOutcome

Terminal outcome returned by runAuthorSession.
Properties
§readonly error?:ErrorError attached when the session cancelled due to an explicit failure
§readonly message?:stringFormatted commit message (populated whenever the draft reached the preview step)
§readonly status:SessionStatusStatus tag describing how the session ended
§interface

SessionType

Conventional-commit type entry shown in the type step's choice list.
Properties
§readonly description?:stringShort description rendered as a prompt hint
§readonly name:stringBare identifier (e.g. feat, fix)
§interface

StagedPathsOptions

Options accepted by the default staged-paths provider.
Properties
§readonly cwd:stringWorking directory used as the git command cwd
§readonly timeout?:numberTimeout in milliseconds (default: 30000)
§interface

Step

A named step in an authoring session.
Properties
§readonly id:stringStable identifier used by goto and for debugging
§interface

StepResult

Outcome produced by a step implementation.
Properties
§readonly error?:ErrorError attached when status === 'cancelled'
§readonly gotoStepId?:stringTarget step id when status === 'goto'
§readonly status:StepStatusStatus tag used by the runner to decide how to proceed
§interface

SubjectCaseOptions

Options for the subject-case rule.
Properties
§readonly cases:unknownOne or more accepted case forms. A subject passing any accepted form is valid.
§interface

TypeEnumOptions

Options for the type-enum rule.
Properties
§readonly types:unknownAllowed commit type identifiers. Empty array disables the check.
§interface

CommitValidationResult

Aggregated outcome of running a ruleset over a commit.
Properties
§readonly errors:unknownError-level violations (blocking)
§readonly valid:booleanTrue when no error-level violations were recorded
§readonly warnings:unknownWarn-level violations (non-blocking)

◆ Types

§type

CommitSource

Source of how a commit relates to a project.
Classification determines whether a commit should appear in a project's changelog and how its scope should be displayed.
type CommitSource = "direct-scope" | "direct-file" | "unscoped-file" | "indirect-dependency" | "indirect-infra" | "unscoped-global" | "excluded"
§type

InfrastructureMatcher

Infrastructure matcher function type.
Returns true if the commit should be classified as infrastructure-related. Matchers are composable - combine them using anyOf, allOf, and not.
type InfrastructureMatcher = (context: InfrastructureMatchContext) => boolean
§type

CommitExecutor

Signature for executing the final git commit.
type CommitExecutor = (message: string) => void | Promise<void>
§type

CommitType

Conventional commit type identifier (e.g., 'feat', 'fix', 'docs').
type CommitType = "feat" | "fix" | "docs" | "style" | "refactor" | "perf" | "test" | "build" | "ci" | "chore" | "revert" | string
§type

PartialSessionConfig

Partial shape accepted by createAuthorSession/loadCommitConfig.
type PartialSessionConfig = Partial<SessionConfig>
§type

RuleConfig

Configuration tuple for a single rule in a ruleset.
A bare [level] entry disables the rule when level is 'off', or enables it with no options otherwise. The [level, options] form passes rule-specific options through to the rule's check() implementation.
type RuleConfig = unknown | unknown
§type

RuleLevel

Severity level for a rule in a ruleset.
type RuleLevel = "off" | "warn" | "error"
§type

RuleResult

Aggregated list of violations produced by the engine for a single ruleset run.
type RuleResult = unknown
§type

Ruleset

Mapping from rule name to its config tuple. Rules not present in the map are treated as 'off' by the engine.
type Ruleset = Readonly<Record<string, RuleConfig>>
§type

SessionStatus

Session outcome status constants.
type SessionStatus = Readonly<{ Cancelled: "cancelled"; Committed: "committed" }>
§type

StagedPathsProvider

Signature for resolving the staged file paths the session operates on.
type StagedPathsProvider = (options: StagedPathsProviderOptions) => unknown
§type

StepStatus

Result status constants returned by steps.
type StepStatus = Readonly<{ Cancelled: "cancelled"; Done: "done"; Goto: "goto" }>
§type

SubjectCase

Supported subject-case modes.
type SubjectCase = "sentence-case" | "lower-case" | "upper-case" | "kebab-case" | "snake-case" | "start-case"

● Variables

§type

CI_SCOPE_MATCHER

Matches common CI/CD scopes.
Matches: ci, cd, build, pipeline, workflow, actions
§type

DEFAULT_INFRA_SCOPE_MATCHER

Combined matcher for common infrastructure patterns.
Combines CI, tooling, and tool-prefix matchers.
§type

TOOL_PREFIX_MATCHER

Matches tool-prefixed scopes (e.g., tool-package, tool-scripts).
§type

TOOLING_SCOPE_MATCHER

Matches common tooling/workspace scopes.
Matches: tooling, workspace, monorepo, nx, root
§type

bodyStep

Step that prompts for an optional commit body. Empty input leaves draft.body unset (the formatter then omits the body section).
§type

breakingStep

Step that asks whether the commit introduces a breaking change. A positive answer follows up with a description prompt; the description is written to draft.breakingDescription and is eventually synthesized into a BREAKING CHANGE: footer by formatCommitMessage.
§type

BUILT_IN_RULES

Registry of built-in rules the engine knows how to run, keyed by rule name.
§type

COMMIT_TYPES

§type

commitStep

Step that renders the draft one last time and hands the message to the configured commit executor. When config.skipCommit is true the step short-circuits so the caller receives the formatted message without touching the working tree.
§type

CONFIG_FILE_NAMES

Supported config file names, searched in this order per directory.
§type

CONVENTIONAL_TYPES

Conventional Commits default type enum used by the preset.
§type

conventionalPreset

Default ruleset mirroring @commitlint/config-conventional's baseline.
| Rule | Level | Options | | ------------------ | ----- | ------------------------ | | type-enum | error | CONVENTIONAL_TYPES | | subject-empty | error | — | | scope-enum | off | — | | subject-case | off | — | | header-max-length | warn | { maxLength: 72 } | | imperative-mood | warn | — |
§type

conventionalStepPreset

Default ordered step list used by createAuthorSession when the caller does not supply their own sequence. Matches decision D8: resolve-scope → type → scope → subject → body → breaking → issues → preview → commit.
§type

DEFAULT_EXCLUDE_SCOPES

Default scopes to exclude from changelogs.
These represent repository-level or infrastructure changes that typically don't belong in individual project changelogs.
§type

DEFAULT_IMPERATIVE_WORDLIST

Default past-tense → imperative word map used when options are omitted.
§type

DEFAULT_PROJECT_PREFIXES

Default project name prefixes that can be stripped for scope matching.
§type

DEFAULT_SESSION_TYPES

Default type enum rendered by the type step when the caller does not supply their own list. Each conventional type is paired with a short hint.
§type

EMPTY_STAGING_MESSAGE

Error thrown to the runner when the staging area is empty.
§type

headerMaxLengthRule

Rule that fails when the reconstructed header (type(scope)!: subject) exceeds the configured maximum length.
§type

imperativeMoodRule

Rule that reports a warning when the first subject word (case-insensitive) matches a known past-tense form. Never blocks; intended as a nudge.
§type

issuesStep

Step that optionally collects issue references (e.g. fixes #123, re #456) and appends them to draft.footers using the # separator form.
The step is additive: existing footers stay, and any breaking-change footer synthesized later by the formatter is unaffected.
§type

MINOR_TYPES

§type

NO_SCOPE_CANDIDATES_MESSAGE

Error thrown when the scope step cannot proceed because no candidates were found.
§type

PATCH_TYPES

§type

PREVIEW_RESTART_STEP_ID

Step id the preview jumps back to when the user rejects the draft.
§type

previewStep

Step that renders the accumulated draft as the final commit message and asks the user to confirm. A negative answer jumps back to the type step while keeping the draft intact for round-trip editing. Validation warnings are printed before the prompt.
§type

RELEASE_TYPES

§type

resolveScopeStep

Non-prompt step that computes the candidate scope list and default scope.
Calls config.stagedPathsProvider() → discoverScopes → defaultScope and writes the results into the context. Cancels the session when the staging area is empty (decision E1a).
§type

scopeEnumRule

Rule that fails when any scope on the commit is not in the configured allow-list. A commit with no scopes (empty array) always passes; when scopes are required, pair this rule with a separate scope-empty check.
§type

scopeStep

Step that prompts the user to pick the commit scope(s) from the candidate list discovered by resolve-scope. Respects scopeOptional (cancels with an actionable error when no candidates exist and scope is required) and scopeMulti (multiselect vs. single-select).
§type

subjectCaseRule

Rule that fails when the commit subject does not match any of the configured case forms. An empty subject always passes (handled by subject-empty).
§type

subjectEmptyRule

Rule that fails when the commit subject is empty or whitespace-only.
§type

subjectStep

Step that prompts for the commit subject. Strips the trailing period, trims edges, and enforces a non-empty subject. When headerMaxLength is set, a live countdown re-renders on every keystroke (green → yellow → red as the remaining budget shrinks).
§type

typeEnumRule

Rule that fails when the commit type is not in the configured allow-list.
§type

typeStep

Step that prompts the user for the commit type. Uses the searchable select prompt and seeds the cursor from any existing ctx.draft.type (so a preview → cancel restart re-opens on the previous choice).