Public API Reference
This page documents the complete configuration schema for Commit Wizard v0.0.2. All fields listed here are supported and stable.
Top-level structure
version = 1 # Optional; currently always 1
[commit]
[branch]
[pr]
[check]
[push]
[versioning]
[changelog]
[registry]
[registries]
[rules]
[commit] — Commit message policy
Controls commit type definitions, scope requirements, subject length, and breaking change handling.
commit.subject_max_length
Type: u32
Default: 72
Description: Maximum length for the commit subject line.
[commit]
subject_max_length = 72
commit.use_emojis
Type: bool
Default: false
Description: Include emoji in commit types when displaying options.
[commit]
use_emojis = true # Shows ✨ next to feat, 🐛 next to fix, etc.
commit.types.<type>
Description: Define allowed commit types and their versioning impact.
Per-type fields:
emoji(string) — Emoji representationdescription(string) — Human-readable descriptionbump(enum:"major","minor","patch") — Semantic version impactsection(string) — Changelog section name
[commit.types.feat]
emoji = "✨"
description = "A new feature"
bump = "minor"
section = "Features"
[commit.types.fix]
emoji = "🐛"
description = "A bug fix"
bump = "patch"
section = "Bug Fixes"
[commit.types.docs]
emoji = "📚"
description = "Documentation changes"
bump = "patch"
section = "Documentation"
[commit.types.chore]
emoji = "🔧"
description = "Maintenance tasks"
bump = "patch"
section = "Chores"
Built-in defaults: feat, fix, chore, docs, style, refactor, perf, test
You can add custom types:
[commit.types.release]
emoji = "🚀"
description = "Release preparation"
bump = "patch"
section = "Release"
commit.scopes
Controls scope availability and constraints.
commit.scopes.mode
Type: enum ("disabled", "optional", "required")
Default: "optional"
[commit.scopes]
mode = "optional" # Users may include a scope but aren't required
mode = "required" # Every commit needs a scope
mode = "disabled" # Hide scope field entirely
commit.scopes.restrict_to_defined
Type: bool
Default: false
Description: If true, users can only use scopes defined in [commit.scopes.definitions].
[commit.scopes]
restrict_to_defined = true
commit.scopes.definitions.<scope>
Description: Define allowed scopes with metadata.
Per-scope fields:
title(string) — Display namedescription(string) — Scope purposetypes(array of strings, optional) — Limit this scope to specific commit types
[commit.scopes.definitions.api]
title = "API"
description = "REST API endpoints and services"
types = ["feat", "fix"] # Only these types can use this scope
[commit.scopes.definitions.ui]
title = "User Interface"
description = "Frontend components and styling"
[commit.scopes.definitions.db]
title = "Database"
description = "Schema changes, migrations"
commit.breaking
Controls breaking change handling.
commit.breaking.require_header
Type: bool
Default: false
Description: If true, breaking changes must use the ! suffix after scope.
[commit.breaking]
require_header = true
# Users must write: feat(api)!: remove old endpoint
commit.breaking.require_footer
Type: bool
Default: false
Description: If true, breaking changes must include a BREAKING CHANGE: footer.
[commit.breaking]
require_footer = true
# Users must add: BREAKING CHANGE: The old endpoint is removed
commit.breaking.footer_key
Type: string
Default: "BREAKING CHANGE"
Description: The footer token to use for breaking change description.
[commit.breaking]
footer_key = "BREAKING CHANGE"
commit.breaking.footer_keys
Type: array of strings
Default: []
Description: Additional footer tokens to recognize as breaking changes.
[commit.breaking]
footer_keys = ["BREAKING", "BREAKING-CHANGE"]
commit.breaking.emoji
Type: string
Default: "💥"
Description: Emoji to display for breaking changes.
[commit.breaking]
emoji = "💥"
commit.breaking.emoji_mode
Type: enum ("prefix", "suffix", "replace")
Default: "prefix"
Description: Where to place the breaking change emoji in output.
[commit.breaking]
emoji_mode = "prefix" # 💥 feat(api): ...
emoji_mode = "suffix" # feat(api)! 💥: ...
emoji_mode = "replace" # 💥(api): ...
commit.protected
Controls commit protection on protected branches.
commit.protected.allow
Type: bool
Default: true
Description: Allow committing to protected branches.
commit.protected.force
Type: bool
Default: false
Description: Allow git commit --amend on protected branches.
commit.protected.warn
Type: bool
Default: true
Description: Warn when committing to a protected branch.
[commit.protected]
allow = false # Prevent commits to protected branches
force = false # No amend on protected branches
warn = true # Show warning if attempting
commit.ticket
Ticket reference requirements (e.g., Jira ticket, GitHub issue number).
commit.ticket.required
Type: bool
Default: false
commit.ticket.pattern
Type: string (regex)
Default: none
Description: Regex pattern for valid ticket IDs.
[commit.ticket]
required = true
pattern = "PROJ-\\d+" # Matches: PROJ-123, PROJ-999
pattern = "#\\d+" # Matches: #123, #999
pattern = "([A-Z]+-\\d+|#\\d+)" # Multiple formats
commit.ticket.source
Type: enum ("branch", "prompt", "branch_or_prompt", "disabled")
Default: "disabled"
Description: Where to extract ticket references from.
[commit.ticket]
source = "branch" # Extract from branch name: feature/PROJ-123/my-feature
source = "prompt" # Ask user
source = "branch_or_prompt" # Try branch first, prompt if not found
source = "disabled" # Don't look for tickets
commit.ticket.header_format
Type: string
Default: "[{ticket}] "
Description: Format string for the ticket reference in the subject. Use {ticket} as placeholder.
[commit.ticket]
header_format = "[{ticket}] " # [PROJ-123] my message
header_format = "({ticket}) " # (PROJ-123) my message
header_format = "{ticket}: " # PROJ-123: my message
[branch] — Branch policy
branch.remote
Type: string
Default: "origin"
Description: Default remote name for operations.
branch.protected
Type: array of strings
Default: ["main", "master"]
Description: Branch name patterns (glob-style) that are protected.
[branch]
protected = ["main", "master", "develop", "release/*", "hotfix/*"]
branch.naming.pattern
Type: string
Default: none
Description: Required branch naming pattern (regex).
[branch.naming]
pattern = "^(feature|bugfix|hotfix)/[a-z0-9-]+$"
# Enforces: feature/my-feature, bugfix/issue-123, hotfix/critical
[pr] — Pull Request policy
Note: Basic structure defined; full PR integration in v0.0.3+.
pr.enabled
Type: bool
Default: false
pr.title.require_conventional
Type: bool
Default: false
Description: PR title must follow Conventional Commit format.
pr.title.require_ticket
Type: bool
Default: false
Description: PR title must include a ticket reference.
pr.title.scope_mode
Type: enum ("disabled", "optional", "required")
Default: "optional"
pr.branch.check_source
Type: bool
Default: true
Description: Validate source branch naming.
pr.branch.check_target
Type: bool
Default: true
Description: Validate target branch is allowed.
pr.branch.source_pattern
Type: string
Default: none
pr.branch.target_allowed
Type: array of strings
Default: ["main"]
[check] — Commit validation
check.require_conventional
Type: bool
Default: true
Description: Checked commits must follow Conventional Commit format.
check.commits.enabled
Type: bool
Default: true
check.commits.enforce_on
Type: enum ("all_branches", "protected_branches", "none")
Default: "protected_branches"
Description: When to enforce strict checking.
[check.commits]
enforce_on = "protected_branches" # Only enforce on main, master, etc.
enforce_on = "all_branches" # Check every commit everywhere
enforce_on = "none" # Disabled (but can be run manually)
[push] — Push policy
push.allow.protected
Type: bool
Default: false
Description: Allow pushing to protected branches.
push.allow.force
Type: bool
Default: false
Description: Allow force push.
push.check.commits
Type: bool
Default: true
Description: Run commit validation before push.
push.check.branch_policy
Type: bool
Default: true
Description: Check branch naming and protection rules.
[push]
[push.allow]
protected = false
force = false
[push.check]
commits = true
branch_policy = true
[versioning] — Semantic versioning
versioning.tag_prefix
Type: string
Default: "v"
Description: Prefix for version tags.
[versioning]
tag_prefix = "v" # Tags: v1.0.0, v1.1.0
tag_prefix = "" # Tags: 1.0.0, 1.1.0
tag_prefix = "release-" # Tags: release-1.0.0
[changelog] — Changelog generation
changelog.output
Type: string (file path)
Default: "CHANGELOG.md"
Description: Where to write the changelog.
changelog.format
Type: enum ("markdown", "json")
Default: "markdown"
changelog.header.use
Type: bool
Default: true
Description: Include a header section in the changelog.
changelog.header.title
Type: string
Default: "Changelog"
changelog.header.description
Type: string
Default: ""
changelog.layout.group_by
Type: array of strings
Default: ["type"]
Description: How to organize entries. Options: "type", "scope".
changelog.layout.section_order
Type: array of strings
Description: Order of sections (commit types) in changelog.
[changelog.layout]
section_order = ["feat", "fix", "perf", "docs", "refactor", "test", "chore"]
changelog.layout.scope_order
Type: array of strings
Default: []
Description: Order of scopes if grouping by scope.
changelog.layout.show_scope
Type: bool
Default: true
changelog.layout.show_empty_sections
Type: bool
Default: false
Description: Include section headers even if no commits in that section.
changelog.layout.show_empty_scopes
Type: bool
Default: false
changelog.layout.misc_section
Type: string
Default: "Miscellaneous"
Description: Section name for commits without a type.
changelog.layout.unreleased_label
Type: string
Default: "Unreleased"
Description: Section name for commits not yet released.
changelog.layout.date_format
Type: string
Default: "%Y-%m-%d"
Description: Date format string (strftime-compatible).
changelog.sections.<type>
Description: Customize how sections appear in changelog.
[changelog.sections.feat]
title = "Features"
order = 0 # Display first
[changelog.sections.fix]
title = "Bug Fixes"
order = 1
[changelog.sections.docs]
title = "Documentation"
order = 10
[release] — Release workflow (structural in v0.0.2, full support in v0.0.3+)
release.enabled
Type: bool
Default: false
release.source_branch
Type: string
Default: "main"
release.target_branch
Type: string
Default: "main"
release.branch_format
Type: string
Default: "release/{version}"
release.hotfix_pattern
Type: string
Default: "hotfix/*"
release.validation.require_clean_worktree
Type: bool
Default: true
release.validation.fail_if_tag_exists
Type: bool
Default: true
release.validation.fail_if_release_branch_exists
Type: bool
Default: true
release.finish.tag
Type: bool
Default: true
release.finish.push
Type: bool
Default: true
release.finish.backmerge_branch
Type: string
Default: "main"
[registry] — Active registry selection
registry.use
Type: string
Description: Key name under [registries] to use.
registry.section
Type: string
Description: Section within the selected registry.
[registry]
use = "org-standards"
section = "frontend"
[registries] — Available registries
Define multiple registries; select one via [registry].use.
[registries.org-standards]
url = "https://github.com/my-org/cw-standards.git"
ref = "main"
section = "shared"
sections = ["shared", "frontend", "backend"]
[registries.team-config]
url = "/opt/shared/team-registry" # Local path
Per-registry fields:
url(string) — Git URL or local pathref(string) — Git reference (branch, tag, commit)section(string) — Default section to usesections(array of strings, optional) — Available sections (informational)
[rules] — Reusable values
Free-form TOML that defines values referenced elsewhere as @rules.<key>.
[rules]
allowed_scopes = ["api", "ui", "db", "auth"]
ticket_pattern = "PROJ-\\d+"
protected_branches = ["main", "staging"]
release_checklist = ["tests", "docs", "changelog"]
Then reference them:
[commit.scopes.definitions]
# Could reference @rules.allowed_scopes in future versions
[commit.ticket]
pattern = "@rules.ticket_pattern"
Current status: Rules are stored but full cross-field referencing coming in v0.0.3+.
Summary of defaults
Here's a minimal .cwizard.toml that activates all defaults:
version = 1
And here's what's actually applied:
[commit]
subject_max_length = 72
use_emojis = false
[commit.types.feat]
emoji = "✨"
description = "A new feature"
bump = "minor"
section = "Features"
[commit.types.fix]
emoji = "🐛"
description = "A bug fix"
bump = "patch"
section = "Bug Fixes"
# ... (more built-in types)
[commit.scopes]
mode = "optional"
restrict_to_defined = false
[commit.breaking]
require_header = false
require_footer = false
footer_key = "BREAKING CHANGE"
emoji = "💥"
emoji_mode = "prefix"
[branch]
remote = "origin"
protected = ["main", "master"]
[check.commits]
enforce_on = "protected_branches"
[push.allow]
protected = false
force = false
[push.check]
commits = true
branch_policy = true
[versioning]
tag_prefix = "v"
[changelog]
output = "CHANGELOG.md"
format = "markdown"
[changelog.layout]
group_by = ["type"]
show_scope = true
misc_section = "Miscellaneous"
unreleased_label = "Unreleased"
date_format = "%Y-%m-%d"
Customization paths
| Goal | Start here |
|---|---|
| Require scopes on all commits | [commit.scopes] |
| Add team-specific scope definitions | [commit.scopes.definitions.<scope>] |
| Enforce ticket references | [commit.ticket] |
| Restrict push to protected branches | [push.allow] |
| Customize changelog layout | [changelog.layout] |
| Use shared registry config | [registry] + [registries] |
| Define reusable values | [rules] |
See Configuration Guides for practical examples.