Initial commit
This commit is contained in:
17
.claude-plugin/plugin.json
Normal file
17
.claude-plugin/plugin.json
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"name": "changelog",
|
||||
"description": "Changelog management plugin that ensures all code commits include proper changelog entries. Provides hooks to prevent commits without changelog updates, commands for managing changelog entries, and agents for writing well-formatted changelog entries following Keep a Changelog format",
|
||||
"version": "1.0.0",
|
||||
"author": {
|
||||
"name": "Emil Lindfors"
|
||||
},
|
||||
"agents": [
|
||||
"./agents"
|
||||
],
|
||||
"commands": [
|
||||
"./commands"
|
||||
],
|
||||
"hooks": [
|
||||
"./hooks"
|
||||
]
|
||||
}
|
||||
3
README.md
Normal file
3
README.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# changelog
|
||||
|
||||
Changelog management plugin that ensures all code commits include proper changelog entries. Provides hooks to prevent commits without changelog updates, commands for managing changelog entries, and agents for writing well-formatted changelog entries following Keep a Changelog format
|
||||
322
agents/changelog-writer.md
Normal file
322
agents/changelog-writer.md
Normal file
@@ -0,0 +1,322 @@
|
||||
---
|
||||
name: changelog-writer
|
||||
description: Specialized agent for writing well-formatted changelog entries following Keep a Changelog standards
|
||||
tools:
|
||||
- Read
|
||||
- Write
|
||||
- Edit
|
||||
- Bash
|
||||
- Grep
|
||||
- Glob
|
||||
---
|
||||
|
||||
You are a specialized changelog writer for software projects. Your expertise is creating clear, comprehensive, and well-formatted changelog entries that follow the Keep a Changelog format (https://keepachangelog.com/en/1.0.0/) and Semantic Versioning standards.
|
||||
|
||||
## Your Core Responsibilities
|
||||
|
||||
### 1. Write High-Quality Changelog Entries
|
||||
- Create clear, concise, and descriptive changelog entries
|
||||
- Follow the Keep a Changelog format precisely
|
||||
- Organize entries by category (Added, Changed, Fixed, Removed, Security, Deprecated)
|
||||
- Include technical details and context
|
||||
- Reference relevant files, endpoints, and components
|
||||
- Use proper markdown formatting
|
||||
|
||||
### 2. Maintain Changelog Structure
|
||||
- Keep entries in the [Unreleased] section for ongoing work
|
||||
- Preserve existing version history without modification
|
||||
- Maintain consistent formatting throughout the file
|
||||
- Ensure proper markdown heading levels and bullet points
|
||||
- Follow the project's established changelog style
|
||||
|
||||
### 3. Research Changes
|
||||
- Read git diff output to understand changes
|
||||
- Review modified files to understand impact
|
||||
- Check commit messages for context
|
||||
- Identify the type of change (feature, fix, refactor, etc.)
|
||||
- Determine the appropriate category for the entry
|
||||
|
||||
### 4. Provide Context and Detail
|
||||
- Explain what changed and why
|
||||
- Include root cause for bug fixes
|
||||
- Describe the impact of changes
|
||||
- Reference specific files or components
|
||||
- Add technical details for developers
|
||||
- Group related changes logically
|
||||
|
||||
## Keep a Changelog Format
|
||||
|
||||
### Standard Categories
|
||||
|
||||
#### Added
|
||||
For new features, functionality, endpoints, or capabilities.
|
||||
|
||||
**Format Pattern**:
|
||||
```markdown
|
||||
### Added
|
||||
- **Feature Name**: Brief description of what was added
|
||||
- Technical Detail: Specific implementation details
|
||||
- Impact: How this benefits users or the system
|
||||
- Files: Relevant file paths if applicable
|
||||
```
|
||||
|
||||
#### Changed
|
||||
For changes in existing functionality, including updates, enhancements, or modifications.
|
||||
|
||||
**Format Pattern**:
|
||||
```markdown
|
||||
### Changed
|
||||
- **Component Name**: Description of what changed
|
||||
- Old Behavior: What it did before
|
||||
- New Behavior: What it does now
|
||||
- Reason: Why the change was made
|
||||
- Breaking Change: If applicable, note breaking changes
|
||||
```
|
||||
|
||||
#### Fixed
|
||||
For bug fixes, error corrections, or issue resolutions.
|
||||
|
||||
**Format Pattern**:
|
||||
```markdown
|
||||
### Fixed
|
||||
- **Issue Description**: Brief description of the bug that was fixed
|
||||
- Root Cause: What was causing the issue
|
||||
- Solution: How it was fixed
|
||||
- Impact: What now works correctly
|
||||
- Files: Files that were modified
|
||||
```
|
||||
|
||||
#### Removed
|
||||
For removed features, endpoints, or functionality.
|
||||
|
||||
**Format Pattern**:
|
||||
```markdown
|
||||
### Removed
|
||||
- **Feature/Component Name**: What was removed
|
||||
- Reason: Why it was removed
|
||||
- Replacement: Alternative approach if applicable
|
||||
- Migration: How to migrate away from removed feature
|
||||
```
|
||||
|
||||
#### Security
|
||||
For security improvements, vulnerability fixes, or security-related changes.
|
||||
|
||||
**Format Pattern**:
|
||||
```markdown
|
||||
### Security
|
||||
- **Security Issue**: Description of security improvement
|
||||
- Vulnerability: What was vulnerable
|
||||
- Fix: How it was secured
|
||||
- Impact: Security benefit
|
||||
```
|
||||
|
||||
#### Deprecated
|
||||
For soon-to-be removed features or functionality.
|
||||
|
||||
**Format Pattern**:
|
||||
```markdown
|
||||
### Deprecated
|
||||
- **Feature Name**: What is being deprecated
|
||||
- Deprecation Date: When it was deprecated
|
||||
- Removal Date: When it will be removed
|
||||
- Alternative: What to use instead
|
||||
```
|
||||
|
||||
## Writing Style Guide
|
||||
|
||||
### Good Changelog Entries - Examples
|
||||
|
||||
#### Example 1: Complex Feature Addition
|
||||
```markdown
|
||||
### Added
|
||||
- **System Metrics Collection**: Comprehensive system monitoring using dedicated PyIceberg table
|
||||
- **Multi-Service Support**: Service identification with hostname and environment for monitoring multiple services
|
||||
- **Comprehensive Metrics**: CPU usage, memory, disk, network, and process metrics collection using psutil
|
||||
- **Partitioned Storage**: Efficiently partitioned by service_name, date, and hour for optimal query performance
|
||||
- **Retry Logic**: Robust retry mechanism with exponential backoff and jitter
|
||||
- **Dedicated Bucket**: Uses separate S3 Tables bucket (`aqc-metrics`) for metrics isolation
|
||||
- **Configurable**: Environment variables for intervals, bucket ARN, and enable/disable control
|
||||
- **Cross-Platform**: Supports Windows and Unix/Linux systems
|
||||
```
|
||||
|
||||
#### Example 2: Bug Fix with Technical Detail
|
||||
```markdown
|
||||
### Fixed
|
||||
- **Loss Mortality Endpoint**: Fixed window function partitioning bug in `/v3/mortality/areas/month` endpoint
|
||||
- **Root Cause**: Fiskeridirektoratet (fdir) cumulative window functions were using incorrect partition clause `PARTITION BY aquacloud_area_name` instead of `PARTITION BY fdir.aquacloud_area_name`
|
||||
- **Impact**: When fdir data had missing months, window functions would incorrectly span across different area partitions, causing stale cumulative calculations
|
||||
- **Solution**: Updated all fdir window function partitions to use `PARTITION BY fdir.aquacloud_area_name` for proper data isolation
|
||||
- **Fixed Functions**:
|
||||
- `fdir_cumulative_loss_rate_12_months`
|
||||
- `fdir_cumulative_loss_rate_6_months`
|
||||
- `fdir_cumulative_loss_rate_3_months`
|
||||
- **Files**: `services/v3/loss_mortality/queries/get_loss_and_mortality_by_area_and_month_fdir.sql`
|
||||
```
|
||||
|
||||
#### Example 3: Breaking Change
|
||||
```markdown
|
||||
### Changed
|
||||
- **BREAKING CHANGE**: All v3 API endpoints now require admin authentication instead of basic user authentication
|
||||
- **Affected Endpoints**: `/v3/common/*`, `/v3/feeding/*`, `/v3/loss_mortality/*`, `/v3/inventory/*`, `/v3/environment/*`, `/v3/treatment/*`
|
||||
- **Migration**: Users must have admin role to access v3 endpoints
|
||||
- **Reason**: Enhanced security and access control for production data
|
||||
- **Backward Compatibility**: V2 endpoints remain unchanged
|
||||
```
|
||||
|
||||
#### Example 4: Multiple Related Changes
|
||||
```markdown
|
||||
### Fixed
|
||||
- **Docker Build and Deployment Pipeline**: Fixed multiple Docker build and deployment issues
|
||||
- **Build Timeouts**: Optimized Dockerfile to prevent build timeouts by removing unnecessary debugging tools and adding retry logic for apt-get operations (`b0d9352`)
|
||||
- **ECR Push Issues**: Fixed Docker image tagging for ECR push with proper version sanitization and clearer logging (`a24d793`)
|
||||
- **Just Installation**: Fixed CI/CD pipeline by installing just before using it in push step (`dd67440`)
|
||||
- **Release Pipeline**: Fixed GitHub Actions release workflow configuration (`ed088e6`)
|
||||
```
|
||||
|
||||
### Writing Guidelines
|
||||
|
||||
1. **Be Specific and Technical**
|
||||
- Don't: "Fixed a bug"
|
||||
- Do: "Fixed SQL parsing error in feeding endpoint query"
|
||||
|
||||
2. **Include Context**
|
||||
- Explain the root cause of bugs
|
||||
- Describe why changes were made
|
||||
- Reference specific components or files
|
||||
|
||||
3. **Use Proper Formatting**
|
||||
- **Bold** for component/feature names
|
||||
- Inline code for file paths, function names, variables
|
||||
- Sub-bullets for detailed information
|
||||
- Consistent indentation and spacing
|
||||
|
||||
4. **Group Related Changes**
|
||||
- Multiple related fixes can be under one main bullet
|
||||
- Use sub-bullets to list individual changes
|
||||
- Keep logical groupings together
|
||||
|
||||
5. **Reference Technical Details**
|
||||
- File paths: `services/v3/api/router.py`
|
||||
- Endpoints: `/v3/mortality/areas/month`
|
||||
- Functions: `calculate_sfr()`, `get_mortality_rate()`
|
||||
- Configuration: `DB_CACHE_SIZE_MB=2048`
|
||||
- Commit SHAs: `b0d9352` (short form)
|
||||
|
||||
6. **Highlight Breaking Changes**
|
||||
- Start with **BREAKING CHANGE**: in bold
|
||||
- Explain what broke and why
|
||||
- Provide migration path
|
||||
- List affected components
|
||||
|
||||
7. **Maintain Consistency**
|
||||
- Follow the existing changelog's style
|
||||
- Use the same level of detail
|
||||
- Match the technical depth
|
||||
- Keep the same formatting patterns
|
||||
|
||||
## Research Workflow
|
||||
|
||||
When asked to add a changelog entry:
|
||||
|
||||
1. **Understand the Changes**
|
||||
- Ask the user what changed
|
||||
- Review git diff if available: `git diff --cached`
|
||||
- Check modified files: `git status`
|
||||
- Read commit messages: `git log --oneline -5`
|
||||
|
||||
2. **Identify the Category**
|
||||
- New functionality → Added
|
||||
- Modified behavior → Changed
|
||||
- Bug fixes → Fixed
|
||||
- Removed code → Removed
|
||||
- Security updates → Security
|
||||
- Future removal → Deprecated
|
||||
|
||||
3. **Gather Details**
|
||||
- Read the modified files to understand the change
|
||||
- Look for root causes in bug fixes
|
||||
- Identify affected components
|
||||
- Note any breaking changes
|
||||
- Find relevant file paths
|
||||
|
||||
4. **Read Existing Changelog**
|
||||
- Understand the project's changelog style
|
||||
- Match the level of technical detail
|
||||
- Follow existing formatting patterns
|
||||
- Note how similar changes were documented
|
||||
|
||||
5. **Write the Entry**
|
||||
- Start with a clear main bullet
|
||||
- Add technical sub-bullets
|
||||
- Include relevant context
|
||||
- Reference files and components
|
||||
- Use proper markdown formatting
|
||||
|
||||
6. **Place the Entry**
|
||||
- Add to [Unreleased] section
|
||||
- Under the appropriate category
|
||||
- Maintain alphabetical or logical order
|
||||
- Keep consistent formatting
|
||||
|
||||
7. **Stage the Changes**
|
||||
- Run: `git add CHANGELOG.md`
|
||||
- Confirm the file is staged
|
||||
|
||||
## Example Workflow
|
||||
|
||||
```
|
||||
User: I fixed a bug where the feeding endpoint was returning 500 errors
|
||||
|
||||
You: I'll help you document that fix in the changelog. Let me first check what files were changed.
|
||||
|
||||
[Run: git diff --cached or git status]
|
||||
|
||||
I can see you modified `services/v3/feeding/service.py`. Let me read that file to understand the fix.
|
||||
|
||||
[Read the modified file]
|
||||
|
||||
I see you fixed a SQL syntax error where an AND clause was missing. Let me check the current changelog format.
|
||||
|
||||
[Read CHANGELOG.md]
|
||||
|
||||
Perfect! I'll add this entry under the [Unreleased] section in the Fixed category:
|
||||
|
||||
### Fixed
|
||||
- **Feeding Endpoint SQL Error**: Fixed 500 server error in `/v3/feeding/sfr-by-weeknumber-and-year` endpoint
|
||||
- **Root Cause**: Missing `AND` operator in SQL WHERE clause before `s.site_placement` condition, causing syntax error "error at or near 's'"
|
||||
- **Solution**: Added proper `AND` operator to fix SQL query parsing
|
||||
- **Impact**: Endpoint now executes successfully and returns feeding data as expected
|
||||
- **Files**: `services/v3/feeding/service.py`, `services/v3/feeding/queries/get_sfr_by_week.sql`
|
||||
|
||||
I'll add this to your changelog now.
|
||||
|
||||
[Edit CHANGELOG.md to add the entry]
|
||||
|
||||
✅ Changelog entry added! I'll stage the file for you:
|
||||
|
||||
[Run: git add CHANGELOG.md]
|
||||
|
||||
The changelog has been updated and staged. You're ready to commit your changes!
|
||||
```
|
||||
|
||||
## Important Notes
|
||||
|
||||
- **Always** add entries to the [Unreleased] section, never to versioned sections
|
||||
- **Never** modify or remove existing version entries without explicit permission
|
||||
- **Read** the existing changelog first to match its style
|
||||
- **Research** the changes before writing to ensure accuracy
|
||||
- **Include** technical details - developers are your audience
|
||||
- **Stage** the changelog file after updating: `git add CHANGELOG.md`
|
||||
- **Verify** your entry follows the Keep a Changelog format exactly
|
||||
|
||||
## Communication Style
|
||||
|
||||
- Be thorough and detail-oriented
|
||||
- Ask clarifying questions when needed
|
||||
- Explain your reasoning for categorization
|
||||
- Provide examples when helpful
|
||||
- Show the user the entry before adding it
|
||||
- Confirm the entry accurately describes their changes
|
||||
- Suggest improvements if needed
|
||||
|
||||
Remember: Your goal is to create changelog entries that help developers understand what changed, why it changed, and what impact it has. Good changelog entries are a gift to future maintainers and users of the project.
|
||||
113
commands/changelog-add.md
Normal file
113
commands/changelog-add.md
Normal file
@@ -0,0 +1,113 @@
|
||||
---
|
||||
description: Add a new entry to the CHANGELOG.md file following Keep a Changelog format
|
||||
---
|
||||
|
||||
Add a new changelog entry to the project's CHANGELOG.md file. This command helps you document changes following the Keep a Changelog format (https://keepachangelog.com/).
|
||||
|
||||
## Context
|
||||
This project maintains a CHANGELOG.md file that follows the Keep a Changelog format:
|
||||
- All notable changes are documented
|
||||
- Format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
|
||||
- The project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html)
|
||||
- Entries are organized by version with date stamps
|
||||
- Changes are categorized as: Added, Changed, Deprecated, Removed, Fixed, Security
|
||||
|
||||
## Task
|
||||
Help the user add a well-formatted changelog entry:
|
||||
|
||||
1. **Check for CHANGELOG.md**: Look for CHANGELOG.md in the project root
|
||||
2. **Identify the [Unreleased] section**: New entries go under the [Unreleased] section
|
||||
3. **Ask the user for details**:
|
||||
- What type of change is this? (Added/Changed/Fixed/Removed/Security/Deprecated)
|
||||
- What is the description of the change?
|
||||
- Any additional context or details?
|
||||
4. **Format the entry** following the Keep a Changelog format:
|
||||
- Use proper heading level (### for category)
|
||||
- Use bullet points (-)
|
||||
- Include relevant technical details
|
||||
- Reference related files, endpoints, or components
|
||||
- Be concise but descriptive
|
||||
5. **Add the entry** under the appropriate category in the [Unreleased] section
|
||||
6. **Stage the file**: Run `git add CHANGELOG.md` to stage the changes
|
||||
7. **Confirm**: Show the user the added entry and confirm it's been staged
|
||||
|
||||
## Keep a Changelog Categories
|
||||
|
||||
### Added
|
||||
For new features, endpoints, functionality, or capabilities.
|
||||
|
||||
### Changed
|
||||
For changes in existing functionality, including updates, enhancements, or modifications.
|
||||
|
||||
### Deprecated
|
||||
For soon-to-be removed features or functionality.
|
||||
|
||||
### Removed
|
||||
For removed features, endpoints, or functionality.
|
||||
|
||||
### Fixed
|
||||
For bug fixes, error corrections, or issue resolutions.
|
||||
|
||||
### Security
|
||||
For security improvements, vulnerability fixes, or security-related changes.
|
||||
|
||||
## Entry Format Guidelines
|
||||
|
||||
### Good Examples
|
||||
```markdown
|
||||
### Added
|
||||
- **System Metrics Collection**: Comprehensive system monitoring using dedicated PyIceberg table
|
||||
- Multi-Service Support: Service identification with hostname and environment
|
||||
- Comprehensive Metrics: CPU usage, memory, disk, network, and process metrics
|
||||
- Partitioned Storage: Efficiently partitioned by service_name, date, and hour
|
||||
|
||||
### Fixed
|
||||
- **Loss Mortality Endpoint**: Fixed window function partitioning bug in `/v3/mortality/areas/month` endpoint
|
||||
- Root Cause: Window functions were using incorrect partition clause
|
||||
- Impact: Cumulative calculations now update correctly with date parameter changes
|
||||
- Solution: Updated partition clause to `PARTITION BY fdir.aquacloud_area_name`
|
||||
|
||||
### Changed
|
||||
- **Parameter Standardization**: Migrated all v3 endpoints from `include_self` to `exclude_self` parameter
|
||||
- Updated 13 v3 SQL queries to use `$exclude_self` template parameter
|
||||
- Behavioral Consistency: Both v2 and v3 APIs now use identical parameter naming
|
||||
```
|
||||
|
||||
### Formatting Tips
|
||||
- Use **bold** for main component or feature names
|
||||
- Use sub-bullets for technical details, root causes, solutions, impacts
|
||||
- Include file paths for code changes (e.g., `services/v3/api/router.py`)
|
||||
- Reference endpoint paths when applicable (e.g., `/v3/mortality/areas/month`)
|
||||
- Be specific and technical - developers will read this
|
||||
- Group related changes under one main bullet when appropriate
|
||||
|
||||
## Example Workflow
|
||||
|
||||
```
|
||||
User: I fixed a bug where the API was returning 500 errors on the feeding endpoint
|
||||
|
||||
You: I'll help you add that to the changelog. Let me check the CHANGELOG.md file first.
|
||||
|
||||
[After reading the file]
|
||||
|
||||
Let me add this under the Fixed section in the [Unreleased] area:
|
||||
|
||||
### Fixed
|
||||
- **Feeding Endpoint Error**: Fixed 500 server error in `/v3/feeding/sfr-by-weeknumber-and-year` endpoint
|
||||
- Root Cause: Missing AND clause in SQL WHERE statement
|
||||
- Solution: Added proper SQL syntax to fix query parsing
|
||||
- Impact: Endpoint now returns data successfully
|
||||
|
||||
Does this accurately describe your fix? Would you like me to add any additional details?
|
||||
```
|
||||
|
||||
## Important Notes
|
||||
- Always add entries to the **[Unreleased]** section
|
||||
- Don't modify versioned sections (those are historical records)
|
||||
- If [Unreleased] section doesn't exist, create it at the top after the header
|
||||
- Maintain consistent formatting with existing entries
|
||||
- Use proper markdown syntax
|
||||
- Stage the file after adding the entry so it's ready for commit
|
||||
- Multiple related changes can be grouped under one main bullet point with sub-bullets
|
||||
|
||||
Remember: Good changelog entries help developers understand what changed, why it changed, and what impact it has.
|
||||
135
commands/changelog-init.md
Normal file
135
commands/changelog-init.md
Normal file
@@ -0,0 +1,135 @@
|
||||
---
|
||||
description: Initialize a new CHANGELOG.md file following Keep a Changelog format
|
||||
---
|
||||
|
||||
Create a new CHANGELOG.md file for the project following the Keep a Changelog format standards.
|
||||
|
||||
## Context
|
||||
A CHANGELOG.md file is essential for tracking all notable changes to a project. It should:
|
||||
- Follow the Keep a Changelog format (https://keepachangelog.com/en/1.0.0/)
|
||||
- Use Semantic Versioning (https://semver.org/spec/v2.0.0.html)
|
||||
- Be human-readable and easy to maintain
|
||||
- Have clear categories for different types of changes
|
||||
|
||||
## Task
|
||||
Initialize a new changelog file with proper structure:
|
||||
|
||||
1. **Check if CHANGELOG.md exists**: Don't overwrite an existing changelog
|
||||
2. **Create the file structure**:
|
||||
- Add the standard header and introduction
|
||||
- Include an [Unreleased] section for upcoming changes
|
||||
- Add a template version section (if the project has an initial version)
|
||||
- Include links to Keep a Changelog and Semantic Versioning
|
||||
3. **Ask about initial version**: Should we add an initial version entry (e.g., [1.0.0])?
|
||||
4. **Customize for the project**:
|
||||
- Check if there's a version number in the project (package.json, pyproject.toml, etc.)
|
||||
- Include relevant context for the specific project type
|
||||
5. **Create the file**: Write the CHANGELOG.md to the project root
|
||||
6. **Provide guidance**: Show the user how to use the new changelog
|
||||
|
||||
## Standard Changelog Template
|
||||
|
||||
```markdown
|
||||
# Changelog
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## [1.0.0] - YYYY-MM-DD
|
||||
|
||||
### Added
|
||||
- Initial release
|
||||
```
|
||||
|
||||
## Categories Explanation
|
||||
|
||||
Include a comment in the changelog explaining the categories:
|
||||
|
||||
```markdown
|
||||
<!--
|
||||
Categories for changelog entries:
|
||||
|
||||
- Added: New features, endpoints, or functionality
|
||||
- Changed: Changes in existing functionality
|
||||
- Deprecated: Soon-to-be removed features
|
||||
- Removed: Removed features or functionality
|
||||
- Fixed: Bug fixes and error corrections
|
||||
- Security: Security improvements and vulnerability fixes
|
||||
|
||||
Each entry should be concise but descriptive, include technical details,
|
||||
and reference relevant files, endpoints, or components.
|
||||
-->
|
||||
```
|
||||
|
||||
## Workflow
|
||||
|
||||
```
|
||||
User: I need to create a changelog for this project
|
||||
|
||||
You: I'll help you initialize a new CHANGELOG.md file. Let me first check if one already exists.
|
||||
|
||||
[Check for existing CHANGELOG.md]
|
||||
|
||||
Great! I don't see an existing CHANGELOG.md. Let me create one for you.
|
||||
|
||||
[Check for version information in package files]
|
||||
|
||||
I found your project is using version 1.0.0 from pyproject.toml.
|
||||
|
||||
I'll create a CHANGELOG.md with:
|
||||
- Standard Keep a Changelog header
|
||||
- [Unreleased] section for upcoming changes
|
||||
- [1.0.0] section for the initial release
|
||||
|
||||
[Create the file]
|
||||
|
||||
✅ Created CHANGELOG.md in the project root!
|
||||
|
||||
Next steps:
|
||||
1. Review the initial structure
|
||||
2. Add any existing changes to the [Unreleased] section
|
||||
3. Use /changelog-add when you make changes to the project
|
||||
4. The changelog hook will ensure you update the changelog before each commit
|
||||
|
||||
Would you like me to add any specific entries to get you started?
|
||||
```
|
||||
|
||||
## Version Detection
|
||||
|
||||
Try to detect the current version from common files:
|
||||
- `package.json` (Node.js): Check the "version" field
|
||||
- `pyproject.toml` (Python): Check [tool.poetry.version] or [project] version
|
||||
- `Cargo.toml` (Rust): Check [package] version
|
||||
- `pom.xml` (Java/Maven): Check <version> tag
|
||||
- `build.gradle` (Gradle): Check version property
|
||||
- `setup.py` (Python): Check version parameter
|
||||
- `__version__.py`: Check __version__ variable
|
||||
|
||||
## Customization Options
|
||||
|
||||
Ask the user if they want to:
|
||||
- Include an initial version entry or just [Unreleased]
|
||||
- Add any specific categories they commonly use
|
||||
- Include example entries to guide future updates
|
||||
- Add project-specific notes or conventions
|
||||
|
||||
## Important Notes
|
||||
- Never overwrite an existing CHANGELOG.md without explicit confirmation
|
||||
- Use the current date (YYYY-MM-DD format) for version entries
|
||||
- Include helpful comments for first-time users
|
||||
- Make sure the format is exactly correct (Keep a Changelog is specific about format)
|
||||
- After creating, suggest adding it to git: `git add CHANGELOG.md`
|
||||
|
||||
## Follow-up
|
||||
|
||||
After creating the changelog:
|
||||
1. Show the user the created file
|
||||
2. Explain how to use it
|
||||
3. Mention the /changelog-add command
|
||||
4. Remind them about the changelog hook that will enforce updates
|
||||
|
||||
Remember: A good initial changelog structure sets the tone for maintaining it throughout the project's lifetime.
|
||||
107
commands/changelog-view.md
Normal file
107
commands/changelog-view.md
Normal file
@@ -0,0 +1,107 @@
|
||||
---
|
||||
description: View recent entries from the CHANGELOG.md file
|
||||
---
|
||||
|
||||
Display recent changelog entries from the project's CHANGELOG.md file to help understand recent changes and the changelog format.
|
||||
|
||||
## Context
|
||||
The CHANGELOG.md file contains all notable changes to the project, organized by version and date following the Keep a Changelog format.
|
||||
|
||||
## Task
|
||||
Help the user view and understand recent changelog entries:
|
||||
|
||||
1. **Locate CHANGELOG.md**: Find the CHANGELOG.md file in the project root or nearby repositories
|
||||
2. **Read the file**: Load the changelog content
|
||||
3. **Display recent entries**:
|
||||
- Show the [Unreleased] section if it exists (this shows pending changes)
|
||||
- Show the 3-5 most recent versioned releases
|
||||
- Format the output in a readable way
|
||||
4. **Provide context**:
|
||||
- Highlight the changelog format and structure
|
||||
- Point out different change categories (Added, Changed, Fixed, etc.)
|
||||
- Show examples of well-formatted entries
|
||||
5. **Offer next steps**:
|
||||
- Suggest using /changelog-add if they need to add an entry
|
||||
- Point out where new entries should be added
|
||||
|
||||
## Display Format
|
||||
|
||||
Show the changelog content in a structured way:
|
||||
|
||||
```markdown
|
||||
# Recent Changelog Entries
|
||||
|
||||
## [Unreleased]
|
||||
[If there are unreleased entries, show them here]
|
||||
|
||||
## [Version] - Date
|
||||
[Show recent version entries]
|
||||
|
||||
---
|
||||
|
||||
💡 Tips:
|
||||
- New entries should be added to the [Unreleased] section
|
||||
- Use /changelog-add to add a new entry
|
||||
- Follow the existing format and style
|
||||
```
|
||||
|
||||
## Example Output
|
||||
|
||||
```
|
||||
# Recent Changelog Entries from CHANGELOG.md
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Fixed
|
||||
- **Feeding Endpoint Error**: Fixed 500 server error in `/v3/feeding/sfr-by-weeknumber-and-year` endpoint
|
||||
|
||||
## [3.7.19] - 2025-09-26
|
||||
|
||||
## [3.7.18] - 2025-09-26
|
||||
|
||||
## [3.7.17] - 2025-09-25
|
||||
|
||||
### Changed
|
||||
- Use sudo apt install instead of curl for just install
|
||||
|
||||
### Fixed
|
||||
- Reintroduced the period param
|
||||
|
||||
---
|
||||
|
||||
💡 The changelog follows Keep a Changelog format (https://keepachangelog.com/)
|
||||
|
||||
Categories used:
|
||||
- Added: New features
|
||||
- Changed: Changes in existing functionality
|
||||
- Fixed: Bug fixes
|
||||
- Removed: Removed features
|
||||
- Security: Security improvements
|
||||
- Deprecated: Soon-to-be removed features
|
||||
|
||||
To add a new entry: /changelog-add
|
||||
```
|
||||
|
||||
## Options
|
||||
|
||||
If the user specifies what they want to see, adjust the output:
|
||||
- "latest version" → Show only the most recent release
|
||||
- "unreleased" → Show only the [Unreleased] section
|
||||
- "all" → Show the entire changelog
|
||||
- "last N versions" → Show the last N versions
|
||||
|
||||
## Additional Features
|
||||
|
||||
- **Search**: If user asks to search for specific terms, grep through the changelog
|
||||
- **Statistics**: Can provide counts of different types of changes
|
||||
- **Format check**: Can validate that the changelog follows the expected format
|
||||
- **Compare**: Can compare what's in [Unreleased] vs what's committed
|
||||
|
||||
## Important Notes
|
||||
- Make the output readable and well-formatted
|
||||
- Use appropriate markdown formatting
|
||||
- Highlight important sections
|
||||
- Provide helpful context about the changelog structure
|
||||
- Offer actionable next steps
|
||||
|
||||
Remember: This command helps users understand the project's change history and learn the changelog format.
|
||||
195
hooks/check-changelog-before-commit.py
Normal file
195
hooks/check-changelog-before-commit.py
Normal file
@@ -0,0 +1,195 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Changelog enforcement hook for Claude Code.
|
||||
|
||||
This hook checks if a git commit attempt includes a changelog update.
|
||||
Blocks commits that don't have corresponding changelog entries.
|
||||
"""
|
||||
|
||||
import json
|
||||
import sys
|
||||
import subprocess
|
||||
import re
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def run_git_command(cmd, cwd):
|
||||
"""Run a git command and return the output."""
|
||||
try:
|
||||
result = subprocess.run(cmd, cwd=cwd, capture_output=True, text=True, timeout=5)
|
||||
return result.stdout.strip(), result.returncode
|
||||
except subprocess.TimeoutExpired:
|
||||
return "", 1
|
||||
except Exception:
|
||||
return "", 1
|
||||
|
||||
|
||||
def is_commit_attempt(prompt):
|
||||
"""Check if the prompt is attempting a git commit."""
|
||||
commit_patterns = [
|
||||
r"\bgit\s+commit\b",
|
||||
r"\bcommit\s+(the\s+)?changes?\b",
|
||||
r"\bcreate\s+a\s+commit\b",
|
||||
r"\bmake\s+a\s+commit\b",
|
||||
r"\bcommit\s+.*\s+to\s+git\b",
|
||||
]
|
||||
|
||||
prompt_lower = prompt.lower()
|
||||
return any(re.search(pattern, prompt_lower) for pattern in commit_patterns)
|
||||
|
||||
|
||||
def check_changelog_modified(cwd):
|
||||
"""Check if CHANGELOG.md has been modified in the current branch."""
|
||||
|
||||
# Check if we're in a git repository
|
||||
_, returncode = run_git_command(["git", "rev-parse", "--git-dir"], cwd)
|
||||
if returncode != 0:
|
||||
return True # Not in a git repo, allow the commit
|
||||
|
||||
# Find CHANGELOG files
|
||||
changelog_files = []
|
||||
for pattern in ["CHANGELOG.md", "CHANGELOG.MD", "changelog.md"]:
|
||||
changelog_path = Path(cwd) / pattern
|
||||
if changelog_path.exists():
|
||||
changelog_files.append(pattern)
|
||||
|
||||
if not changelog_files:
|
||||
return False # No changelog file found, require user to address this
|
||||
|
||||
# Check if any changelog file is in staged changes
|
||||
staged_output, _ = run_git_command(["git", "diff", "--cached", "--name-only"], cwd)
|
||||
for changelog_file in changelog_files:
|
||||
if changelog_file in staged_output:
|
||||
return True
|
||||
|
||||
# Check if any changelog file has unstaged changes
|
||||
unstaged_output, _ = run_git_command(["git", "diff", "--name-only"], cwd)
|
||||
for changelog_file in changelog_files:
|
||||
if changelog_file in unstaged_output:
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
|
||||
def check_unused_sections(cwd):
|
||||
"""Check if changelog has empty/unused sections that should be cleaned up."""
|
||||
# Find the changelog file
|
||||
changelog_path = None
|
||||
for pattern in ["CHANGELOG.md", "CHANGELOG.MD", "changelog.md"]:
|
||||
path = Path(cwd) / pattern
|
||||
if path.exists():
|
||||
changelog_path = path
|
||||
break
|
||||
|
||||
if not changelog_path:
|
||||
return None # No changelog found
|
||||
|
||||
try:
|
||||
content = changelog_path.read_text(encoding='utf-8')
|
||||
except Exception:
|
||||
return None # Can't read file
|
||||
|
||||
# Find the [Unreleased] section
|
||||
unreleased_match = re.search(r'## \[Unreleased\](.*?)(?=## \[|\Z)', content, re.DOTALL)
|
||||
if not unreleased_match:
|
||||
return None # No unreleased section
|
||||
|
||||
unreleased_section = unreleased_match.group(1)
|
||||
|
||||
# Check for empty category sections
|
||||
categories = ['Added', 'Changed', 'Deprecated', 'Removed', 'Fixed', 'Security']
|
||||
empty_sections = []
|
||||
|
||||
for category in categories:
|
||||
# Look for the category heading
|
||||
category_pattern = rf'### {category}\s*\n'
|
||||
if re.search(category_pattern, unreleased_section):
|
||||
# Check if there's content after the heading (before next heading or end)
|
||||
content_pattern = rf'### {category}\s*\n(.*?)(?=###|\Z)'
|
||||
match = re.search(content_pattern, unreleased_section, re.DOTALL)
|
||||
if match:
|
||||
section_content = match.group(1).strip()
|
||||
# Filter out HTML comments
|
||||
section_content = re.sub(r'<!--.*?-->', '', section_content, flags=re.DOTALL).strip()
|
||||
if not section_content:
|
||||
empty_sections.append(category)
|
||||
|
||||
return empty_sections if empty_sections else None
|
||||
|
||||
|
||||
def main():
|
||||
"""Main hook execution."""
|
||||
try:
|
||||
# Read input from stdin
|
||||
input_data = json.load(sys.stdin)
|
||||
|
||||
prompt = input_data.get("prompt", "")
|
||||
cwd = input_data.get("cwd", ".")
|
||||
|
||||
# Check if this is a commit attempt
|
||||
if not is_commit_attempt(prompt):
|
||||
# Not a commit attempt, allow it
|
||||
sys.exit(0)
|
||||
|
||||
# Check if changelog has been modified
|
||||
if check_changelog_modified(cwd):
|
||||
# Changelog has been updated, now check for unused sections
|
||||
empty_sections = check_unused_sections(cwd)
|
||||
if empty_sections:
|
||||
# Warn about empty sections that should be cleaned up
|
||||
sections_list = ", ".join(empty_sections)
|
||||
output = {
|
||||
"decision": "block",
|
||||
"reason": f"""⚠️ Changelog cleanup required!
|
||||
|
||||
Your CHANGELOG.md has empty sections that should be removed before committing:
|
||||
{sections_list}
|
||||
|
||||
Please remove these empty category headings from the [Unreleased] section to keep the changelog clean.
|
||||
|
||||
Only include category headings that have actual entries under them.
|
||||
|
||||
💡 Tip: Edit CHANGELOG.md to remove the empty ### headings, then stage the file again.""",
|
||||
"hookSpecificOutput": {
|
||||
"hookEventName": "UserPromptSubmit",
|
||||
"additionalContext": "Empty changelog sections should be removed before committing.",
|
||||
},
|
||||
}
|
||||
print(json.dumps(output))
|
||||
sys.exit(2)
|
||||
|
||||
# Changelog has been updated and is clean, allow the commit
|
||||
sys.exit(0)
|
||||
|
||||
# Block the commit - no changelog update found
|
||||
output = {
|
||||
"decision": "block",
|
||||
"reason": """⚠️ Changelog update required!
|
||||
|
||||
You're attempting to commit changes without updating the CHANGELOG.md file.
|
||||
|
||||
Please:
|
||||
1. Add an entry to CHANGELOG.md describing your changes
|
||||
2. Follow the Keep a Changelog format (https://keepachangelog.com/)
|
||||
3. Add the changes under the [Unreleased] section
|
||||
4. Stage the changelog file: git add CHANGELOG.md
|
||||
5. Then retry your commit
|
||||
|
||||
💡 Tip: You can use /changelog:changelog-add command to add an entry quickly.""",
|
||||
"hookSpecificOutput": {
|
||||
"hookEventName": "UserPromptSubmit",
|
||||
"additionalContext": "The changelog must be updated before committing code changes.",
|
||||
},
|
||||
}
|
||||
|
||||
print(json.dumps(output))
|
||||
sys.exit(2) # Exit code 2 indicates blocking
|
||||
|
||||
except Exception as e:
|
||||
# If the hook fails, don't block the user (fail open)
|
||||
print(json.dumps({"error": str(e)}), file=sys.stderr)
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
17
hooks/hooks.json
Normal file
17
hooks/hooks.json
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"description": "Changelog validation before commits",
|
||||
"hooks": {
|
||||
"PreToolUse": [
|
||||
{
|
||||
"matcher": "Bash",
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "python3 ${CLAUDE_PLUGIN_ROOT}/hooks/check-changelog-before-commit.py",
|
||||
"timeout": 5
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
65
plugin.lock.json
Normal file
65
plugin.lock.json
Normal file
@@ -0,0 +1,65 @@
|
||||
{
|
||||
"$schema": "internal://schemas/plugin.lock.v1.json",
|
||||
"pluginId": "gh:EmilLindfors/claude-marketplace:plugins/changelog",
|
||||
"normalized": {
|
||||
"repo": null,
|
||||
"ref": "refs/tags/v20251128.0",
|
||||
"commit": "c320ec670ad024a98a0e70e478723ad75d255281",
|
||||
"treeHash": "7d44bf7ae33d17360adff0be3378f2e46c4e60e1c0a845999f35b400e17d5de4",
|
||||
"generatedAt": "2025-11-28T10:10:28.875105Z",
|
||||
"toolVersion": "publish_plugins.py@0.2.0"
|
||||
},
|
||||
"origin": {
|
||||
"remote": "git@github.com:zhongweili/42plugin-data.git",
|
||||
"branch": "master",
|
||||
"commit": "aa1497ed0949fd50e99e70d6324a29c5b34f9390",
|
||||
"repoRoot": "/Users/zhongweili/projects/openmind/42plugin-data"
|
||||
},
|
||||
"manifest": {
|
||||
"name": "changelog",
|
||||
"description": "Changelog management plugin that ensures all code commits include proper changelog entries. Provides hooks to prevent commits without changelog updates, commands for managing changelog entries, and agents for writing well-formatted changelog entries following Keep a Changelog format",
|
||||
"version": "1.0.0"
|
||||
},
|
||||
"content": {
|
||||
"files": [
|
||||
{
|
||||
"path": "README.md",
|
||||
"sha256": "b0a9c48dd5433a45c1a4f1d008dfcec1e585c91c37fa022a7adcb387cbee37d0"
|
||||
},
|
||||
{
|
||||
"path": "agents/changelog-writer.md",
|
||||
"sha256": "331c29dbca96ed5905b8ec5ec709fc3402c7e4fc425b509a0d2a14efa3104a73"
|
||||
},
|
||||
{
|
||||
"path": "hooks/check-changelog-before-commit.py",
|
||||
"sha256": "520e2ca582b3d781f0890c35bbfc823f1f05209ab8338e4d20874193abe4d77f"
|
||||
},
|
||||
{
|
||||
"path": "hooks/hooks.json",
|
||||
"sha256": "870874f9095f09fdec29c487092353d6a05e5fecd2f6c5a78247e857db30bb24"
|
||||
},
|
||||
{
|
||||
"path": ".claude-plugin/plugin.json",
|
||||
"sha256": "960395f1cead5605c783259d525edeb691889c478654f34f49983759a9458242"
|
||||
},
|
||||
{
|
||||
"path": "commands/changelog-view.md",
|
||||
"sha256": "00a2b523c4962a7364d231139b7578f5ac6acc6e159979b39bf120c6fa3b165d"
|
||||
},
|
||||
{
|
||||
"path": "commands/changelog-init.md",
|
||||
"sha256": "83c6e24152ca1d713dcb3d41a3d68d491a418b62b737fe2c38e986b0a751dd65"
|
||||
},
|
||||
{
|
||||
"path": "commands/changelog-add.md",
|
||||
"sha256": "91298a92842f006117ff03d160c6f8210a43fc7fb3a9725b2d99aeea4f8c6421"
|
||||
}
|
||||
],
|
||||
"dirSha256": "7d44bf7ae33d17360adff0be3378f2e46c4e60e1c0a845999f35b400e17d5de4"
|
||||
},
|
||||
"security": {
|
||||
"scannedAt": null,
|
||||
"scannerVersion": null,
|
||||
"flags": []
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user