mit einem Klick
update-changelog
// Rules and workflows for updating docs/CHANGELOG.md, including version grouping, aggressive consolidation, and GitHub tag-linked release headings.
// Rules and workflows for updating docs/CHANGELOG.md, including version grouping, aggressive consolidation, and GitHub tag-linked release headings.
Use the local ShareX checkout as the source of truth for ShareX.ImageEditor, find the latest upstream commit that touches it, and port or sync the matching changes into the XerahS ShareX.ImageEditor submodule with path-aware diffing and build gates.
Orchestrate XerahS release flow in strict order: run maintenance prep first, update-changelog second (optional only if docs/CHANGELOG.md is intentionally absent), verify build, bump/commit/push/tag while syncing Chocolatey version metadata, monitor GitHub Actions every 2 minutes, ensure standard release notes content, then set pre-release by default (use explicit opt-out for stable). On failures, inspect logs, fix root cause, and retry with the next patch release.
Repository maintenance preparation for XerahS. Use before release or changelog work to sync repositories, inspect submodule state, identify version/changelog needs, and hand off commit/push/version rules to git-workflow.
Bring src/mobile-experimental Avalonia/MAUI mobile apps to feature and behavior parity with src/mobile/ios while preserving native platform feel. Use when comparing the Swift iOS app against XerahS.Mobile.Ava, XerahS.Mobile.Maui, or the experimental iOS share extension, implementing parity gaps, or validating Android/iOS experimental mobile flows.
Bring src/mobile/android to feature and behavior parity with src/mobile/ios while keeping each app native. Use when comparing iOS Swift/SwiftUI/UIKit mobile behavior against Android Kotlin/Jetpack Compose behavior, implementing missing Android features, or validating parity with the Test Android Apps emulator QA workflow.
Maintain XerahS daily development blog drafts under docs/blog using the YYYY/YYYY-MM/blog-YYYYMMDD.md layout. Use when asked to create, update, or consolidate the current UTC+8 blog post from new feature work, bug fixes, build/tooling changes, or recent git history.
| name | update-changelog |
| description | Rules and workflows for updating docs/CHANGELOG.md, including version grouping, aggressive consolidation, and GitHub tag-linked release headings. |
Use the helper script to generate a draft section from commits since the last tag, grouped into changelog categories, with similar commits consolidated by default (see notes below). The default output is intentionally compact: version headings are linked to the GitHub tag URL only when the tag exists, and bullet entries do not include commit hashes. Treat the script output as a draft: before applying or releasing, perform a human-quality grouping pass so repeated commits become concise user-facing bullets instead of a commit log dump.
Script path:
.ai/skills/update-changelog/scripts/update-changelog.ps1
Preview only (prints generated markdown):
powershell -NoProfile -ExecutionPolicy Bypass -File .ai/skills/update-changelog/scripts/update-changelog.ps1
Generate draft from an explicit tag/version and save to a file:
powershell -NoProfile -ExecutionPolicy Bypass -File .ai/skills/update-changelog/scripts/update-changelog.ps1 -FromTag v0.18.9 -Version 0.19.0 -OutputPath build/changelog-draft.md
Apply directly to docs/CHANGELOG.md:
powershell -NoProfile -ExecutionPolicy Bypass -File .ai/skills/update-changelog/scripts/update-changelog.ps1 -FromTag v0.18.9 -Version 0.19.0 -Apply
Per-commit lines only (disables automatic similarity merge):
powershell -NoProfile -ExecutionPolicy Bypass -File .ai/skills/update-changelog/scripts/update-changelog.ps1 -FromTag v0.18.9 -Version 0.19.0 -NoConsolidation
Include commit hashes only when explicitly requested for audit/debug work:
powershell -NoProfile -ExecutionPolicy Bypass -File .ai/skills/update-changelog/scripts/update-changelog.ps1 -FromTag v0.18.9 -Version 0.19.0 -IncludeHashes
Notes:
-Version defaults to root Directory.Build.props.-FromTag defaults to git describe --tags --abbrev=0.## Unreleased).origin. Existing tag example: ## [v0.22.236](https://github.com/ShareX/XerahS/releases/tag/v0.22.236). Unreleased/no-tag example: ## v0.22.237.-IncludeHashes only for temporary audit/debug drafts, not normal release notes.Get-ConsolidationBucket in scripts/update-changelog.ps1 merges commits that match the same similarity bucket (for example: ShareX.ImageEditor in the subject, 2026-... blog draft series, XIP/IEIP docs, Linux install/capture documentation, IEIP/XIP proposal .md create/update under Changed, multipart / S3 multipart). Extend that function when new repetitive patterns appear.#PR, @user) before publishing.Directory.Build.props version.Directory.Build.props history to identify those boundaries.Feature: ... (originally v0.8.1).add, update, finish, polish, refactor, wire, document, and fix when they describe the same user-facing workstream.65bccfb9 in normal changelog entries. The linked version heading is the traceability anchor.298457a under v0.11.0."(#PR_NUMBER, @username)(#77, @Hexeption)McoreD) from having explicit attribution unless they contain significant unique work not covered by other commits. The focus is on crediting other users.Group changes within each version using standard categories:
The helper script maps infrastructure and chore-style commit types into Build unless the commit subject carries a clearer component/category signal.
CRITICAL: Consolidate related commits into single entries to keep the changelog concise and readable.
The automation script does this by default; agents should still edit the draft for narrative quality and any merges the heuristics miss.
## [v0.22.236](https://github.com/ShareX/XerahS/releases/tag/v0.22.236). If the tag does not exist yet, use plain ## v0.22.237.Before (verbose):
- **Media Explorer**: Add `IUploaderExplorer` interface
- **Media Explorer**: Implement S3 file browser
- **Media Explorer**: Implement Imgur album browser
- **Media Explorer**: Add navigation, breadcrumbs, search, filter
- **Media Explorer**: Add bandwidth savings banner
After (consolidated):
- **Media Explorer**: Implement provider file browsing with S3 and Imgur support, including navigation, search, filtering, and CDN thumbnail optimization
Before (mobile features):
- **Mobile**: Add adaptive mobile theming infrastructure
- **Mobile**: Refactor mobile views for adaptive native styling
- **Mobile**: Align mobile heads with native theming defaults
- **Mobile**: Complete sprint 5 mobile theming polish and docs
- **Mobile**: Add mobile upload queue and picker
- **Mobile**: Add mobile upload history screens
After (consolidated):
- **Mobile**: Add adaptive theming infrastructure with native styling polish
- **Mobile**: Add upload queue, picker, and history screens
Before (fixes):
- **Scrolling Capture**: Always auto-scroll to top
- **Scrolling Capture**: Apply workflow settings and refresh hotkeys
- **Scrolling Capture**: Use current scroll position for detection
After (consolidated):
- **Scrolling Capture**: Improve auto-scroll behavior and workflow settings integration
Follow the Keep a Changelog format with Semantic Versioning.
## vX.Y.Z
Use `## [vX.Y.Z](https://github.com/ShareX/XerahS/releases/tag/vX.Y.Z)` only after `vX.Y.Z` exists as a local or remote Git tag.
### Features
- **Component**: Description
### Fixes
- Description
Choose the Changelog Mode
Directory.Build.props version as the target heading.Identify the Range
-FromTag to use git describe --tags --abbrev=0.-FromTag v0.21.2 -Version 0.22.0.v0.PREV_STABLE..v0.LATEST_STABLE.Fallback tag listing:
git tag -l --sort=-version:refname | Select-Object -First 10
Check Target Version
Read the root Directory.Build.props <Version> property unless the user explicitly provided a historical target version.
Consolidate Version Headings
## vX.Y.Z heading for the target version when the tag does not exist yet.## [vX.Y.Z](https://github.com/ShareX/XerahS/releases/tag/vX.Y.Z) only when the tag exists locally or on origin.Categorize Commits
Consolidate Related Entries
Format and Verify
Fix Double-Encoding Mojibake
After any write to docs/CHANGELOG.md, scan for corrupted UTF-8 round-trip artifacts and replace them with their correct Unicode equivalents. This occurs when UTF-8 bytes are decoded and re-encoded by the wrong tool chain. Apply this as a final step every time:
$c = [System.IO.File]::ReadAllText('docs/CHANGELOG.md', [System.Text.Encoding]::UTF8)
# Fix mojibake involving the section-sign byte pair and normalize the output.
$c = $c -replace [char]0x00C2 + [char]0x00A7, [char]0x2014
# Normalize any remaining section-sign corruption.
$c = $c -replace [char]0x00C2 + [char]0x00A7, [char]0x00A7
# Collapse 3+ blank lines
$c = $c -replace "\r?\n", "`n"
$c = $c -replace "`n{3,}", "`n`n"
$c = $c -replace "`n", "`r`n"
[System.IO.File]::WriteAllText('docs/CHANGELOG.md', $c, [System.Text.Encoding]::UTF8)
Common victims to watch for:
—, U+2014)§, U+00A7)ó (U+00F3)# Check latest tags with version-aware sorting.
$tags = git tag -l --sort=-version:refname | Select-Object -First 10
# Check current version.
$version = Select-String -Path "Directory.Build.props" -Pattern '<Version>(.*)</Version>' | ForEach-Object { $_.Matches.Groups[1].Value }
# Preview default current-unreleased changelog section.
powershell -NoProfile -ExecutionPolicy Bypass -File .ai/skills/update-changelog/scripts/update-changelog.ps1
# Apply an explicit current-unreleased range.
powershell -NoProfile -ExecutionPolicy Bypass -File .ai/skills/update-changelog/scripts/update-changelog.ps1 -FromTag v0.21.2 -Version $version -Apply
Why: exact-match replacement tools can fail when CHANGELOG.md contains multi-byte UTF-8 sequences that were double-encoded during a tool round trip. Use PowerShell [System.IO.File] plus Regex instead; it reads raw bytes and avoids exact-literal matching against corrupted text.
Pattern (replace all prerelease sections between two stable headings with new consolidated content):
$cl = 'docs/CHANGELOG.md'
$c = [System.IO.File]::ReadAllText($cl, [System.Text.Encoding]::UTF8)
$newSection = @'
## v0.X.Y
### Features
- ...
### Fixes
- ...
'@
# Use a linked heading instead only when v0.X.Y exists as a local or remote tag.
# (?s) = dotall (. matches newlines); match from first prerelease heading up to (but not including) the previous stable heading
$c = [System.Text.RegularExpressions.Regex]::Replace(
$c,
'(?s)## (?:v0\.FIRST_PRERELEASE|\[v0\.FIRST_PRERELEASE\]\([^)]+\)).*?(?=## (?:v0\.PREV_STABLE|\[v0\.PREV_STABLE\]\([^)]+\)))',
$newSection
)
# Normalize the double-encoded section-sign artifact (C2 A7 → A7).
$c = $c -replace [char]0x00C2 + [char]0x00A7, [char]0x00A7
# Collapse 3+ consecutive blank lines down to 2
$c = $c -replace "\r\n", "`n"
$c = $c -replace "`n{3,}", "`n`n"
$c = $c -replace "`n", "`r`n" # restore CRLF if the repo uses it
[System.IO.File]::WriteAllText($cl, $c, [System.Text.Encoding]::UTF8)
Key points:
(?s) makes . match newlines so the pattern spans the whole block.[char]0x00C2 + [char]0x00A7 to [char]0x00A7) should always run after a regex write to guard against double-encoding.\n{3,} to \n\n) prevents the file from accumulating excess whitespace after sections are removed.