Skip to main content
Goal: Read recent commits from a GitHub repository, categorize them, group by feature area, and output a formatted changelog entry ready to publish. Tools Required: GitHub. Optional: Linear (for richer issue context).

Step 1 — Parse the Request

Identify what to generate:
  • Repo: Which repository? Default to the user’s primary repo if only one is connected.
  • Range: Date range (“last 2 weeks”, “since March 1”), version tags (“v0.2.3..v0.2.4”), or milestone name.
  • Version label: If the user specifies a version, use it. Otherwise, ask or omit.
If the range is unclear, ask:
“Which time period or version range should I cover? For example: ‘last 2 weeks’, ‘since v0.2.3’, or ‘February 2026’.”

Step 2 — Fetch Commits

Use GitHub integration to fetch all commits in the specified range:
  1. List commits for the repo filtered by date or tag range
  2. For each commit, extract: hash, message, author, date
  3. If merge commits reference a PR number, fetch the PR title and description for better context
  4. Filter out noise: merge commits with no meaningful message, version bump-only commits, CI-only changes

Step 3 — Categorize Commits

Classify each commit into exactly one category using the commit message prefix and content:
Prefix / SignalCategory
feat: or feature:New Features
perf: or performance-relatedPerformance & Reliability
fix: or bugfix:Fixes
security: or auth/permission/vulnerability-relatedSecurity & Privacy
chore:, refactor:, docs:, style:, ci:, build:, improvementsImprovements
If a commit has no conventional prefix, read the message body and categorize by intent.

Step 4 — Enrich with Issues (GitHub / Linear)

Extract issue references from commit messages or PR descriptions and fetch context:
PatternSourceExample
#123GitHub Issuefix: resolve search bug (#456)
ABC-123 (letters + dash + number)Linear Issuefeat: add onboarding (ENG-789)
GitHub Issues (always available):
  1. Extract #number references from commit messages and PR bodies
  2. Fetch issue title, description, and labels from GitHub
  3. Use the issue context to write clearer, user-facing descriptions
Linear Issues (if connected):
  1. Extract PREFIX-number references (e.g. ENG-123, CORE-456)
  2. Fetch issue title, description, and priority from Linear
  3. Use Linear context alongside or instead of commit messages for richer descriptions
If both a GitHub issue and Linear issue are referenced in the same commit, prefer the one with more descriptive context.

Step 5 — Group by Feature Area

Within each category, group related commits under a bold feature-area header:
  • Identify clusters: commits touching the same integration, module, or feature
  • Name each group after the feature (e.g. Gmail Integration, Search Improvements, Onboarding Flow)
  • Standalone commits that don’t cluster get listed individually without a group header

Step 6 — Write the Changelog

Generate the changelog using this exact structure. Only include sections that have entries.
## New Features

**[Feature Area Name]**

- [User-facing description of what was added and why it matters]
- [Another capability or detail — keep to 2-3 bullets per feature]

**[Another Feature Area]**

- [Description]

## Performance & Reliability

- **[Bold Label]**: [What improved and the impact — e.g. "2-3x faster retrieval"]
- **[Bold Label]**: [Description]

## Improvements

- **[Bold Label]**: [What changed and why it's better]
- **[Bold Label]**: [Description]

## Fixes

- [One-line description of what was fixed — concise, no bold label needed]
- [Another fix]

## Security & Privacy

- **[Bold Label]**: [What was secured or hardened]
Writing rules:
  1. Lead with the user benefit, not the implementation. Open feature descriptions with what the user can now do or what problem is solved — not what was built.
    • Good: “Time spent in individual statuses is now tracked and available throughout Linear. Hovering over any issue’s status indicator reveals the cumulative time it has spent in each status.”
    • Bad: “Added status duration tracking to the issue model with hover tooltip rendering.”
  2. Features get 2-3 sentences of context. Explain the capability, then explain why it matters or how to use it. Don’t just list what was shipped — frame it as a workflow improvement.
    • Good: “You can now launch your preferred coding tool directly from a Linear issue, with a prefilled prompt that includes the issue ID and all relevant context. No copying or reformatting required.”
    • Bad: “Added deeplink support for coding tools from issues.”
  3. Fixes use **Category:** description format. One line each, concise, past tense.
    • Good: “Search: Fixed duplicate results appearing for broad queries”
    • Good: “Editor: Fixed draft loss when switching tabs while commenting”
    • Bad: “deduplicate invalidated facts at Cypher query level”
  4. Improvements use the same **Category:** description format. Focus on what’s better for the user.
    • Good: “Onboarding: Streamlined setup flow — fewer steps to first memory”
    • Good: “Images: Removed meaningless captions”
  5. Include specific metrics when available. Numbers make improvements tangible.
    • Good: “Faster Search: Agent orchestrator architecture for 2-3x speed improvement”
    • Good: “Pages on Windows open 27% faster”
  6. Don’t include commit hashes, PR numbers, file paths, or internal jargon in the output.
  7. Merge multiple small commits about the same thing into one bullet.
  8. Drop purely internal changes (CI config, linting, dependency bumps) unless they meaningfully affect users.

Step 7 — Clarify User Stories

Before finalizing, review each feature entry. If the commit messages, PR descriptions, and issue context don’t clearly answer “what can the user do now that they couldn’t before?” — ask the user. Flag features where the user story is unclear:
“I have a few features where the commit/issue context doesn’t tell the full story. Can you help me fill in the gaps?
  1. [Feature name] — I see commits around [brief technical summary]. What’s the user-facing story here? What problem does this solve?
  2. [Feature name] — The issue says [quote], but I’m not sure how to frame the benefit. What should users know about this?”
Wait for the user’s response before writing the final changelog. Use their answers to write benefit-first descriptions instead of guessing from code changes. Skip this step if all features have clear user stories from the issues/PRs.

Step 8 — Present and Confirm

Show the generated changelog and ask:
“Here’s the changelog. Want me to adjust anything — add detail, reword, or move items between sections?”
Accept edits and regenerate if needed.

Step 8 — Commit to Repo (Optional)

After the user approves the changelog, offer to commit it directly via GitHub:
“Want me to commit this changelog to the repo? I’ll create a branch and open a PR.”
If yes:
  1. Create a branch: Use create_branch to create a branch named changelog/[month]-[year] (e.g. changelog/march-2026) from main
  2. Commit the file: Use create_or_update_file with:
    • path: The changelog file path (default: docs/opensource/changelog.mdx — confirm with user)
    • content: The approved changelog prepended to the existing file content
    • message: docs: add [Month Year] changelog
    • branch: The branch created in step 1
    • sha: Required when updating an existing file — fetch it first
  3. Open a PR: Use create_pull_request with:
    • title: docs: [Month Year] changelog
    • head: The changelog branch
    • base: main
    • body: Brief summary of what’s included
  4. Share the PR link with the user
If the user prefers to commit manually, just provide the formatted changelog text for copy-paste.

Edge Cases

  • No commits in range → tell the user: “No commits found for [range]. Check the date range or repo.”
  • All commits are internal/CI → “All changes in this range are internal (CI, deps, config). Nothing user-facing to include.”
  • Ambiguous categorization → when a commit spans multiple categories (e.g. a feature that also fixes a bug), pick the primary intent. Mention the secondary benefit in the description.
  • Squash commits with long descriptions → use the PR title as the primary description, pull details from the body.
  • Monorepo with multiple packages → if the user specifies a scope (e.g. “changelog for the webapp”), filter commits by path prefix.