From ac-tools
Validates backlog section completion in BACKLOG.md, generates milestone summaries and release notes from CHANGELOG.md, optionally squashes commits and creates git tags with auto-versioning.
npx claudepluginhub waterplanai/agentic-config --plugin ac-toolsThis skill is limited to using the following tools:
Validate section completion in backlog, then either release or identify gaps.
Generates user-facing changelogs with impact notes and support guidance from git history using Keep a Changelog format. Use for drafting release notes from commits.
Generates and manages changelogs/release notes from git history and Conventional Commits. Supports Keep a Changelog format, breaking change docs, migration guides, audience-specific notes.
Share bugs, ideas, or general feedback.
Validate section completion in backlog, then either release or identify gaps.
All arguments are optional with smart defaults.
Parse $ARGUMENTS into:
| Variable | Source | Required | Default |
|---|---|---|---|
BACKLOG_PATH | 1st arg | No | Auto-detect: BACKLOG.md, specs/backlog.md, or skip |
SECTION | 2nd arg | No | Latest incomplete section, or skip if no backlog |
BASE_BRANCH | 3rd arg | No | origin/main (fetches first) |
VERSION | 4th arg (if not quoted) | No | Auto-bump from VERSION file or latest git tag |
VALIDATION_PROMPT | Last quoted string "..." | No | Auto-derive from checklist |
SKIP_TAG | --skip-tag flag | No | false (tags created by default) |
AUTO_MODE | --auto flag | No | false (confirmation gates enabled) |
WITH_SQUASHED_COMMITS | --with-squashed-commits flag | No | false (squashed commits list excluded by default) |
Parsing Rules:
", treat as VALIDATION_PROMPT--skip-tag flag is present anywhere in arguments, set SKIP_TAG=true--with-squashed-commits flag is present anywhere in arguments, set WITH_SQUASHED_COMMITS=true--auto flag is present anywhere in arguments, set AUTO_MODE=true (skips confirmation gates)$ARGUMENTS triggers full auto-detect modeWhen NO arguments provided:
git fetch origin main 2>/dev/null || git fetch origin master 2>/dev/null
# Try origin/main first, fallback to origin/master
git rev-parse origin/main >/dev/null 2>&1 && echo "origin/main" || echo "origin/master"
Search in order:
BACKLOG.md (root)specs/backlog.mddocs/backlog.mdbacklog.mdIf none found → SKIP backlog validation (proceed without backlog)
Find first incomplete section (has - [ ] items). If all complete → use most recent section.
If SKIP_TAG=false:
Priority order:
VERSION file → parse, increment patch: X.Y.Z → X.Y.(Z+1), prefix with vv*.*.* → increment patchv0.1.0If SKIP_TAG=true:
Set VERSION="" (no version/tag will be created)
# Check if CHANGELOG.md exists and has [Unreleased] content
grep -A 100 "\\[Unreleased\\]" CHANGELOG.md 2>/dev/null | grep -E "^- |^### " | head -20
If CHANGELOG [Unreleased] is EMPTY but commits exist since BASE_BRANCH:
CHANGELOG SYNC REQUIRED
Commits since {BASE_BRANCH}:
{commit list}
But CHANGELOG.md [Unreleased] section is empty.
Please update CHANGELOG.md with these changes before proceeding.
-> STOP and wait for user to update changelog.
If CHANGELOG [Unreleased] has content -> proceed.
Check if AGENTS.md contains project-specific rules:
test -f AGENTS.md && echo "exists" || echo "none"
If exists:
AGENTS.md contentno emojis / DO NOT use emojis -> flag emoji restrictionsproject-agnostic / anonymous -> flag content anonymity requirementsrelative symlinks -> flag symlink requirementsStore parsed rules as PROJECT_RULES for later validation.
BASE_BRANCHCHANGELOG.md must exist with [Unreleased] sectionBACKLOG_PATH must existSECTION must be found in backlogIf any fail → STOP with specific error message.
BACKLOG_PATHSECTION (patterns: #### 1.2, ### Phase 1.2, ## 1.2)- [ ] = unchecked- [x] = checkedFound X items (Y checked, Z unchecked)If no backlog: Skip to Phase 4 with auto-approval path.
VALIDATION_PROMPT provided:Use it as explicit criteria. Spawn validation agent with prompt:
VALIDATE: {VALIDATION_PROMPT}
For each criterion, search codebase and report:
- Status: FOUND | MISSING
- Evidence: file:line references
- Notes: any issues
VALIDATION_PROMPT:For each UNCHECKED item (- [ ]):
Parse item to identify expected:
Search codebase:
Classify:
Display:
✅ CHANGELOG Validated
Changes since {BASE_BRANCH}:
- {N} commits
- Key changes: {summary}
CHANGELOG [Unreleased] entries:
{entries}
Release Configuration:
- Base: {BASE_BRANCH}
- Version: {VERSION or "(no tag)" if SKIP_TAG=true}
- Commits to squash: N
Proceed with squash + tag? (yes/no)
If AUTO_MODE=true: Skip confirmation, proceed directly to squash/tag.
→ On "yes" (or auto): proceed to squash/tag.
Display:
✅ Section {SECTION} COMPLETE
Validated Items:
- [x] Item 1 - evidence: file:line
- [x] Item 2 - evidence: file:line
...
Release Configuration:
- Base: {BASE_BRANCH}
- Version: {VERSION or "(no tag)" if SKIP_TAG=true}
- Commits to squash: N
- CHANGELOG: [Unreleased] → [{VERSION or section name if SKIP_TAG=true}]
Proceed with squash? (yes/no)
If AUTO_MODE=true: Skip confirmation, proceed directly.
On "yes" (or auto):
[x], add checkmark to section header[Unreleased] to new [{VERSION}] - {YYYY-MM-DD} section[Unreleased] section at topSKIP_TAG=true, use section name as headerdocs: mark {SECTION} as completed{branch}-backup/{YYYY}/{MM}/{DD}/001BASE_BRANCHVERSION and SKIP_TAG=false: create annotated tag→ Proceed to Phase 5: Push Confirmation
Generate a standardized commit message following Conventional Commits extended format.
# Get full diff for analysis
git diff {BASE_BRANCH}..HEAD --stat
git diff {BASE_BRANCH}..HEAD --name-status
Parse changed files and categorize by primary change type:
| Type | When to Use |
|---|---|
feat | New feature or capability added |
fix | Bug fix |
docs | Documentation only changes |
chore | Maintenance, deps, configs (no production code) |
refactor | Code restructuring without behavior change |
test | Adding or modifying tests |
style | Formatting, whitespace, linting |
perf | Performance improvements |
build | Build system or external dependencies |
ci | CI/CD configuration changes |
Selection Priority:
feat changes exist -> type = featfix changes exist -> type = fixAnalyze changed file paths to identify scope:
# Get unique top-level directories/components
git diff --name-only {BASE_BRANCH}..HEAD | cut -d'/' -f1-2 | sort -u
Scope Rules:
commands, skills)core)releaserelease or version numberFormat: <type>(<scope>): <description>
Description Rules:
Examples:
feat(commands): add milestone validation workflowfix(parser): handle empty input gracefullydocs(readme): update installation instructionschore(deps): bump typescript to v5.3Structure the body with these sections (include only non-empty):
## Added
- New feature 1
- New feature 2
## Changed
- Modified behavior 1
- Updated component 2
## Fixed
- Bug fix 1
- Issue resolution 2
## Removed
- Deprecated item 1
Content Generation:
git diff {BASE_BRANCH}..HEAD file by fileOnly if WITH_SQUASHED_COMMITS=true, append squashed commit references:
# Get original commit messages
git log --oneline {BASE_BRANCH}..HEAD
Format as:
Squashed commits:
- {sha7} {message}
- {sha7} {message}
- {sha7} {message}
If WITH_SQUASHED_COMMITS=false (default): Omit this section entirely from the commit message.
<type>(<scope>): <description>
## Added
- {additions}
## Changed
- {changes}
## Fixed
- {fixes}
## Removed
- {removals}
<!-- Only if WITH_SQUASHED_COMMITS=true -->
Squashed commits:
- {sha} {message}
- {sha} {message}
<!-- End conditional -->
feat(milestone): add validation workflow with smart defaults
## Added
- Smart defaults resolution for all arguments
- CHANGELOG consistency check
- AGENTS.md validation
- Push confirmation gate
## Changed
- Refactored argument parsing to support quoted strings
- Updated backup branch naming format
## Fixed
- Backlog detection now searches multiple locations
Display:
❌ Section {SECTION} INCOMPLETE
Missing:
1. {item} - {what's missing}
2. {item} - {what's missing}
Implemented but unchecked:
1. {item} - {evidence}
Options:
(A) Create /spec for missing items
(B) Abort - review manually
On "A": Output spec creation commands:
Missing items require specs:
/spec CREATE {item-1-title}
/spec CREATE {item-2-title}
On "B": STOP cleanly.
If PROJECT_RULES were parsed in Phase 0.7, validate all changes against AGENTS.md rules:
git diff --name-only {BASE_BRANCH}..HEAD
For each rule detected, run validation:
Emoji Check (if emoji restriction detected):
# Check all changed .md files for emoji characters
git diff {BASE_BRANCH}..HEAD -- '*.md' | grep -P '[\x{1F300}-\x{1F9FF}]' || echo "clean"
Project-Agnostic/Anonymous Check (if anonymity rule detected):
# Check for personal identifiers, hardcoded usernames, local paths
git diff {BASE_BRANCH}..HEAD | grep -iE '(/Users/[a-z]+|/home/[a-z]+|@[a-z]+\.com)' || echo "clean"
Symlink Check (if symlink rule detected):
# Check for absolute symlinks in changed files
for f in $(git diff --name-only {BASE_BRANCH}..HEAD); do
if [ -L "$f" ]; then
target=$(readlink "$f")
[[ "$target" = /* ]] && echo "ABSOLUTE: $f -> $target"
fi
done
If ANY violations found:
AGENTS.md VIOLATIONS DETECTED
The following changes violate project-specific rules:
Rule: {rule description}
Violations:
- {file}: {violation details}
- {file}: {violation details}
Rule: {rule description}
Violations:
- {file}: {violation details}
Fix these violations before proceeding with release.
-> STOP - Do not proceed to Phase 5.
If NO violations -> proceed to Phase 5.
After successful squash/tag, display:
## Release Prepared Locally
Commit: {sha} {message}
Branch: {branch}
Tag: {VERSION} (if created, otherwise "(none)")
Backup: {backup-branch}
Push to origin?
Commands to execute:
git push --force-with-lease origin {branch}
git push origin {VERSION} # if tag created (SKIP_TAG=false)
Proceed with push? (yes/no)
If AUTO_MODE=true: Skip confirmation, proceed directly with push.
On "yes" (or auto):
git push --force-with-lease origin {branch}VERSION and SKIP_TAG=false: Execute: git push origin {VERSION}On "no" (only when AUTO_MODE=false):
Display manual commands and exit:
Skipped push. Run manually when ready:
git push --force-with-lease origin {branch}
git push origin {VERSION} # if tag was created
| Condition | Action |
|---|---|
| Backlog not found (when path specified) | STOP: "File not found: {path}" |
| Section not found (when specified) | STOP: "Section {SECTION} not found. Available: [list]" |
| No commits to squash | STOP: "No commits between {BASE_BRANCH} and HEAD" |
| Git dirty | STOP: "Uncommitted changes. Commit or stash first." |
| CHANGELOG missing | STOP: "CHANGELOG.md not found or missing [Unreleased] section" |
| CHANGELOG empty + commits exist | STOP: "Update CHANGELOG [Unreleased] before proceeding" |
| AGENTS.md violations | STOP: List violations, require fixes before release |
| User declines | STOP cleanly, no changes |
| Push fails | STOP: show error, suggest manual resolution |
# NO ARGUMENTS - full auto mode
# Auto-detects: backlog, section, base branch, version, validates changelog
/milestone
# With backlog and section (base branch auto-detected)
/milestone specs/backlog.md 1.2
# Full release with all args
/milestone specs/backlog.md 1.2 main v0.1.1-alpha
# With validation prompt
/milestone specs/backlog.md 1.2 main v0.1.1-alpha "NoteMeta extended, parser exists, 20 tests pass"
# Without custom prompt (auto-detect from checklist)
/milestone docs/roadmap.md 2.1 main v2.1.0
# Validate only, no version tag
/milestone CHANGELOG.md phase-3 develop
# Quoted prompt without version
/milestone specs/features.md 4.0 main "API endpoints implemented, auth working"
# Skip tag creation with --skip-tag flag
/milestone specs/backlog.md 1.2 main --skip-tag
# Skip tag with validation prompt
/milestone specs/backlog.md 1.2 main --skip-tag "All tests passing"
# Auto-detect mode without tags
/milestone --skip-tag
# Autonomous mode (skip all confirmation gates)
/milestone --auto
# Autonomous mode with skip-tag (used by orchestrators)
/milestone --skip-tag --auto
# Include squashed commits in message (opt-in)
/milestone --with-squashed-commits