axel:changelog

axel:changelog is a command for coding agents from apiksdev/axel-core. It costs 19 tokens per session (3,256 once invoked), scanned A, original, Apache-2.0.

A command for updating CHANGELOG.md, the file that records project changes, by analyzing Git changes and selecting a semantic version bump. Semantic versioning uses MAJOR.MINOR.PATCH numbers.

In plain words
What is it for?
Use it to create changelog entries and update versions in Claude plugins, Node.js, Python, Rust, PHP, and .NET projects.
Why use it?
It gathers the current working-tree changes and keeps the changelog and supported project version files aligned, while requiring approval for the bump type.

Command

Part of the axel-core plugin — 1 skill, 16 commands, 1 agent shipped together

Install

Getting it into your agent

One page per mod, every tool's command on it. A separate URL per tool would split the same page into five that compete with each other.

agentmods
npx agentmods add commands/apiksdev/axel-core/axel-changelog
Clone the repo
git clone --depth 1 https://github.com/apiksdev/axel-core

Or install axel-core, the plugin that ships this one along with the rest of its 1 skill, 16 commands, 1 agent.

Wrote this? Show the measurements

A badge with what this costs and how it scanned, read live from this page, so it follows the numbers instead of freezing them. Markdown for a README, HTML for a documentation site or a project page.

agentmods badge for axel:changelog

README.md
[![agentmods](https://agentmods.dev/badge/commands/apiksdev/axel-core/axel-changelog.svg)](https://agentmods.dev/commands/apiksdev/axel-core/axel-changelog)
Your own site
<a href="https://agentmods.dev/commands/apiksdev/axel-core/axel-changelog"><img src="https://agentmods.dev/badge/commands/apiksdev/axel-core/axel-changelog.svg" alt="Measured on agentmods" height="20"></a>
Per session 19 Only the description is in the session, so the agent can decide to use it. The body loads when it is invoked.
When invoked 3,256 The whole file, excluding the scripts and references it only reads on demand.
Security scan A 0 findings. Scan, not verified.
Origin original No closer match found in the catalogue.
Token cost

What it costs to keep this loaded

Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.

ModelPer sessionOnce invoked
Fable 5 $0.00019 $0.03256
Opus 5 $0.00010 $0.01628
Sonnet 5 $0.00004 $0.00651
Haiku 4.5 $0.00002 $0.00326

Measured 3d ago against content hash ddb2bbc49b55, method: parsed. Prices are Anthropic first-party input rates as of 2026-08-30, from the pricing page.

Security

Grade A, and why

axel:changelog scanned grade A with 0 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured 3d ago.

A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.

Nothing flagged

None of the 26 patterns this scan looks for appear in this file: no shell pipes, no recursive deletes, no credential paths, no hidden text, no instruction-override or anti-refusal phrasing, no agent-config snooping. That is not a guarantee, it is the absence of the things that are checkable.

commands/axel-changelog.md · 366 lines

How it starts

The opening of the file, as written. The whole thing — 366 lines — stays where its author put it; the contents beside it link to each section on GitHub.

AXEL Command: /axel:changelog

<document type="command">

  <enforcement>
    <![CDATA[
    ⛔ VERSION CONTROL RULES
    - MUST find git repository root using: git rev-parse --show-toplevel
    - MUST operate in git root directory for all git commands
    - MUST be in a git repository
    - MUST use semantic versioning (MAJOR.MINOR.PATCH)
    - MUST exclude whitespace-only changes from analysis
    - MUST get user approval for version bump type
    - MUST work across different project types
    - MUST analyze uncommitted/staged changes (working tree)
    - MUST stop if no changes detected in working tree

    ⛔ PROJECT TYPE DETECTION & SYNCHRONIZATION
    Detect project type and sync version accordingly:
    - Claude Plugin: .claude-plugin/plugin.json → "version" field
    - Node.js/npm: package.json → "version" field
    - Python: pyproject.toml → [project] version or [tool.poetry] version
    - Rust: Cargo.toml → [package] version
    - PHP: composer.json → "version" field
    - .NET: *.csproj or Directory.Build.props → <Version> tag
    - Generic: CHANGELOG.md only (no sync needed)

    Priority order (first match wins):
    1. .claude-plugin/plugin.json
    2. package.json
    3. pyproject.toml
    4. Cargo.toml
    5. composer.json
    6. *.csproj or Directory.Build.props
    7. None (CHANGELOG.md only)

    ⛔ CHANGELOG FORMAT
    - Use bullet list format (not grouped sections)
    - Format: `## [X.Y.Z] - YYYY-MM-DD`
    - Prepend new version above previous versions
    - Use action prefixes: "Added", "Updated", "Removed", "Fixed"
    ]]>
  </enforcement>

  <objective>
    Automate CHANGELOG.md management with version control.
    Analyzes git changes, prompts for semantic version bump,
    and synchronizes CHANGELOG.md with plugin.json.
  </objective>

  <variables>
    <var name="arguments" from="args.*"/>
  </variables>

  <execution flow="linear"><![CDATA[
    Step 1 - Find Git Repository Root:
    - Run: `git rev-parse --show-toplevel`
    - IF error (contains "fatal"):
      → Print: "❌ Error: Not a git repository. CHANGELOG management requires git."
      → STOP
    - Store result in git_root variable
    - Print: "📂 Repository root: ${git_root}"

    Step 2 - Get Current Date:
    - Run cross-platform command:
      → Linux/macOS: `date +%Y-%m-%d`
      → Windows: `powershell -Command "Get-Date -Format 'yyyy-MM-dd'"`
      → Try: `date +%Y-%m-%d 2>/dev/null || powershell -Command "Get-Date -Format 'yyyy-MM-dd'"`
    - Store as: current_date
    - Example: "2026-01-22"

    Step 3 - Check CHANGELOG.md:
    - Change to git root: `cd "${git_root}"`
    - Run: `test -f CHANGELOG.md && echo "exists" || echo "missing"`
    - IF missing:
      → Create new CHANGELOG.md in git root:
        ```markdown
        # Changelog

        ## [0.1.0] - ${current_date}

        - Initial release
        ```
      → Set current_version = "0.1.0"
      → Print: "✅ Created CHANGELOG.md with version 0.1.0"
    - IF exists:
      → Read CHANGELOG.md
      → Extract version from first `## [X.Y.Z]` pattern
      → Store as: current_version
      → Print: "📋 Current version: ${current_version}"

    Step 4 - Detect Project Type & Version File:
    - In git root directory, check files in priority order:
      1. `.claude-plugin/plugin.json` → Claude Plugin
      2. `package.json` → Node.js/npm
      3. `pyproject.toml` → Python
      4. `Cargo.toml` → Rust
      5. `composer.json` → PHP
      6. `*.csproj` or `Directory.Build.props` → .NET
      7. None → Generic project (CHANGELOG only)

    - For first match found:
      → Read version file
      → Store project_type (e.g., "Claude Plugin", "Node.js", "Python", ".NET", etc.)
      → Store version_file (e.g., ".claude-plugin/plugin.json", "MyProject.csproj")
      → Store version_field (e.g., "version" for JSON, "[package] version" for TOML, "<Version>" for XML)
      → Print: "🔍 Detected: ${project_type} project (${version_file})"

    - IF no version file found:
      → Store project_type = "Generic"
      → Store version_file = null
      → Print: "📋 Generic project (CHANGELOG.md only)"

    Step 5 - Check for Uncommitted Changes:
    - Run in git root: `cd "${git_root}" && git status --short`
    - Count non-empty lines
    - Store as: change_count

    - IF change_count == 0:
      → Print: "⚠️ No changes detected in working tree"
      → Print: "💡 Make changes to your project, then run this command"
      → STOP

    - IF change_count > 0:
      → Print: "📝 Found ${change_count} file(s) with changes"
      → Continue

    Step 6 - Analyze Uncommitted Changes (Exclude Whitespace):
    - Get all changed files:
      → Run in git root: `cd "${git_root}" && git status --short`
      → Parse: `??` (untracked), `M` (modified), `D` (deleted), `A` (added)

    - For EACH modified file, check if it has non-whitespace changes:
      → Run in git root: `cd "${git_root}" && git diff --ignore-all-space --quiet -- <file>`
      → Exit code 0 = whitespace-only (SKIP this file)
      → Exit code 1 = real changes (INCLUDE this file)

    - Build final list:
      → Untracked files: Always include (`??`)
      → Modified files: Only if non-whitespace changes (`M`)
      → Deleted files: Always include (`D`)
      → Added files: Always include (`A`)

    - Categorize files:
      → Added: `??`, `A` status
      → Updated: `M` status (only non-whitespace)
      → Removed: `D` status

    - Store change summary
    - Print changes overview with file count

    Step 7 - Prompt Version Bump:
    - Use AskUserQuestion with 4 options:
      1. CURRENT (${current_version} - keep)
         Description: "Update current version entry (for iterative development)"
      2. PATCH (${current_version} → patch)
         Description: "Bug fixes, minor changes (backward compatible)"
      3. MINOR (${current_version} → minor)
         Description: "New features (backward compatible)"
      4. MAJOR (${current_version} → major)
         Description: "Breaking changes (not backward compatible)"
    - Get user selection
    - Store as: bump_type

    Step 8 - Calculate New Version:
    - Parse current_version: split by "." into [major, minor, patch]
    - Calculate new version:
      → IF CURRENT: new_version = "${current_version}" (keep same)
      → IF PATCH: new_version = "${major}.${minor}.${patch + 1}"
      → IF MINOR: new_version = "${major}.${minor + 1}.0"
      → IF MAJOR: new_version = "${major + 1}.0.0"

    - IF CURRENT selected:
      → Print: "🔄 Updating current version: ${current_version}"
    - ELSE:
      → Print: "🔢 New version: ${current_version} → ${new_version}"

    Step 9 - Format Changes for CHANGELOG:
    - Build bullet list from git changes:
      → For each added file: "- Added `filename`"
      → For each modified file: "- Updated `filename`"
      → For each deleted file: "- Removed `filename`"
    - Group intelligently (commands, references, workflows, etc.)
    - Store as: change_bullets

    Step 10 - Update CHANGELOG.md:
    - IF bump_type == "CURRENT":
      → Check if current version entry exists in CHANGELOG
      → Read CHANGELOG content
      → Search for `## [${current_version}]` pattern

      IF FOUND (version entry exists):
        → Extract existing bullets from current version
        → Merge with new change_bullets (avoid duplicates)
        → Use Edit tool to replace:
          OLD: `## [${current_version}] - <old_date>\n<old_bullets>`
          NEW: `## [${current_version}] - ${current_date}\n<merged_bullets>`
        → Print: "✅ Updated existing version ${current_version} in CHANGELOG.md"

      IF NOT FOUND (version entry doesn't exist):
        → Prepend new version entry (same as bump case)
        → Print: "✅ Created version ${current_version} entry in CHANGELOG.md"

    - ELSE (PATCH/MINOR/MAJOR):
      → Use Edit tool to prepend new version:
        OLD:
        ```
        # Changelog

Read the full file on GitHub · 366 lines

Changes

What this file has done since we first saw it

Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.

  1. 3d ago First seen · 366 lines · 19 tokens per session scan A ddb2bbc49b55

Subscribe to this mod's changes

axel:changelog is a command published in the GitHub repository apiksdev/axel-core (7 stars, last pushed 7mo ago), licensed Apache-2.0. It adds 19 tokens to every session and 3,256 once invoked, about $0.0001 per session on Opus 5. A static security scan graded it A with 0 findings. No closer match exists in the catalogue, so it is treated as the original; first seen 2026-08-31.