X402 Git

changelog-writer

Paul Martin

Turns the git log between two tags into a clean changelog.

Top level of the repository
SizeFolderInside
8.5 kBscripts/1 script
3.1 kBskills/1 skill
6 kB(root)2 docs · 1 config file
6 files · 17.6 kB · computed 2026-08-30
SizePath
30 B.gitignore
1.1 kBLICENSE
4.3 kBREADME.md
538 Bpackage.json
8.5 kBscripts/changelog.mjs
3.1 kBskills/changelog.md
computed 2026-08-30 10:14 UTC · analyzer 0.1.0

Already bought this?

View your purchases

README

changelog-writer

Turn git log between two tags into a changelog draft, then edit it into release notes.

One script and one skill. The script reads Conventional Commits when a repo uses them and degrades to a clean flat list when it does not, because most repos do not and a tool that only runs on tidy history is a tool you cannot use today.

No dependencies. Node 18 or newer. It runs git log, git tag and git remote, and writes nothing to git.

Usage

node scripts/changelog.mjs v1.0.0 v1.1.0

Argument handling is the shape you would guess:

CommandRange
changelognewest tag ..HEAD
changelog v1.4.2v1.4.2..HEAD
changelog v1.4.2 (when v1.4.2 is the current tip)v1.4.1..v1.4.2 — "what went into this release"
changelog v1.0.0 v1.1.0exactly that
changelog abc123 HEADany revision works, not only tags

Options

FlagEffect
--repo <url>Base URL for commit and compare links. Defaults to origin, converted from SSH to https.
--out <file>Prepend the block to a file. Newest release ends up at the top of CHANGELOG.md.
--allInclude chore, ci, build and test commits. Off by default; the count is reported instead.
--jsonEmit the parsed commits instead of markdown, so you can group them yourself.
--cwd <dir>Run against another checkout.

Examples

Release notes for a tag you just pushed, with links:

node scripts/changelog.mjs v1.1.0 --repo https://github.com/you/project

Keep CHANGELOG.md current as part of the release:

node scripts/changelog.mjs v1.0.0 v1.1.0 --out CHANGELOG.md
git add CHANGELOG.md && git commit -m "docs: changelog for v1.1.0"

Straight into a GitHub release:

node scripts/changelog.mjs v1.1.0 | gh release create v1.1.0 --notes-file -

Output

## v1.1.0 — 2026-08-30

7 commits since [`v1.0.0...v1.1.0`](https://github.com/you/project/compare/v1.0.0...v1.1.0).

### Breaking changes

- **client:** require an options object ([`9f2c1ab`](https://github.com/you/project/commit/9f2c1ab…))
  `createClient()` no longer accepts a string. Pass `{ url }`.

### Added

- **auth:** device-code login for headless machines ([`3d81f04`](…))

### Fixed

- resume uploads after a dropped connection ([`c0a7e12`](…))

<sub>3 housekeeping commits omitted. Re-run with `--all` to include them.</sub>

Sections come out in reading order: Breaking changes, Added, Fixed, Performance, Changed, Reverted, Documentation, then the noisy ones behind --all. Empty sections are never printed.

How commits are classified

  • type(scope)!: summary is parsed into a type, an optional scope and a summary. The scope becomes the bold lead-in on the bullet.
  • A commit is breaking if the subject has ! before the colon or the body has a BREAKING CHANGE: footer. Breaking commits appear in the breaking section and in their own type's section, so a reader scanning "Added" still sees them.
  • The BREAKING CHANGE: footer text is printed under the bullet. That footer is usually the only place the migration instruction exists.
  • Anything that does not match falls into Other, unchanged.
  • Merge commits are excluded (--no-merges).

The skill

skills/changelog.md is the half a script cannot do. It covers the editing pass: rewriting commit subjects into user-facing entries, merging five commits about one bug into one line, putting an actual instruction in every breaking-change entry, and deleting the sections you have nothing real to say in. It also tells an agent not to invent an entry it cannot verify from the diff, which is the failure mode worth guarding against.

Drop it into wherever your agent reads skills from.

Limitations

  • Tags are compared by git describe reachability, so a changelog across an unmerged branch may surprise you. Pass both ends explicitly when the history is not linear.
  • Reverts are listed, not resolved. A revert: commit and the commit it reverts both appear; deciding they cancel out is an editing judgement.
  • Commit links assume the GitHub URL shape (/commit/<sha>, /compare/a...b). Pass --repo for anything else, or drop the flag and get plain short SHAs.

Licence

MIT. See LICENSE.

Security scan report

Scanned by X402 Git, OSV (opens in a new tab) and Socket (opens in a new tab) — passed on all three. Findings from X402 Git and Socket are listed below.

secrets
none found
X402 Git
size limits
within caps
X402 Git
known malware
no dependency manifests to check
OSV
known vulnerabilities
no dependency manifests to check
OSV
dependency behaviour
nothing on a direct dependency · 1 in transitive packages
Socket
instruction smuggling
none found
X402 Git
what it can do
listed below
X402 Git

What this can do

Tools
none
Runs
scripts/changelog.mjs
Talks to
github.com
Reads
  • FIELD
  • RECORD
At install
nothing runs
Links to
  • api.example.com
  • github.com
Findings (5)
  • LOWscripts/changelog.mjs — Reads the environment variable FIELD
  • LOWscripts/changelog.mjs — Reads the environment variable RECORD
  • LOWscripts/changelog.mjs — Talks to github.com
  • LOWSocket SBOM Resolver — Socket SBOM Resolver (transitive) — no lockfile, so installs are not reproducible
  • LOWscripts/changelog.mjs — Ships the script scripts/changelog.mjs

Releases 2

  1. v1.0.12026-08-30

    Re-cut with lines-of-code and README assets

  2. v1.0.02026-08-30

    feat: initial release

    Turn git log between two tags into a changelog draft, then edit it into release notes.

$5updates $0.10

Buy — go to the order block