# Changeset

> Command: changeset

- Skill: `lofcz/changeset` (Agent Skill)
- Install (CLI): `npx skillmds@latest add lofcz/changeset`
- Raw SKILL.md: https://api.skillmd.com/api/skills/lofcz/changeset/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: lofcz (https://skillmd.com/u/lofcz)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/lofcz/changeset

---


# Changeset

Changesets document package changes for release. Concise bullets, imperative voice, user impact only.

**Core principle:** one action verb + one impact statement = one bullet.

## When To Use

Use when:

- Creating `.changeset/*.md` files
- Documenting package changes: feat, fix, breaking
- Updating Plate UI registry changelog source for copied registry components

Do not use for:

- Internal docs
- Commit messages
- PR descriptions

## Critical Rules

### 1. Core packages: no `minor`

**Forbidden:** `minor` changesets for:

- `@platejs/slate`
- `@platejs/core`
- `platejs`

Use `patch` instead. `minor` on those explodes version bumps across dependents.

```yaml
# Wrong
---
"@platejs/core": minor
---

# Correct
---
"@platejs/core": patch
---
```

Only real breaking changes get `major`.

### 2. One package per file

Never combine packages in one changeset.

```bash
# Wrong
---
'@platejs/core': patch
'@platejs/utils': patch
---

# Correct
.changeset/core-fix-types.md
.changeset/utils-add-helper.md
```

### 3. Always relative to `main`, never last commit

NEVER write a changeset relative to the last commit, staged diff, current
working tree, branch-local plan, or the change you just made. Those are agent
breadcrumbs, not release truth.

Before creating or editing a changeset, answer one question:

> What will a user upgrading from current `main` observe?

Use `main` / `origin/main` as the release baseline. If a symbol, option,
behavior, file, or bug only existed inside the current branch and never existed
on `main`, do **not** write a removal, migration, or breaking changeset for it.
Instead, describe only the final user-visible delta from `main`, or write no
changeset if there is no published package delta.

Write changesets for the user-visible delta from the current `main` branch.

That means:

- describe what users upgrading from `main` need to know
- describe migration steps only when the user actually has to do something
- prefer API shape, runtime behavior, serialized data shape, or config changes
- check whether any named removed/renamed API actually exists on `main` before
  writing removal or migration prose

Do not write:

- last-commit-relative removals for APIs introduced and deleted on the same
  branch
- implementation diary
- architecture rationale
- internal ownership or seam language
- test coverage notes
- "editor-owned", "normalize path", "wrap semantics", or similar internal phrasing unless the public API literally uses those words

If a package changed internally on this branch but has no user-visible delta from
`main`, do not write a changeset for that package.

### 4. Registry work is registry-changelog work

If changes are only under `apps/www/src/registry/`, do **not** write a package changeset.

Use the `registry-changelog` skill instead. It owns the source entry schema,
scaffold command, generator command, and verification check:

```bash
node tooling/scripts/generate-ui-changelog-entries.mjs --new <id> --summary "<summary>" --items <item-a,item-b> --kind <kind>
node tooling/scripts/generate-ui-changelog-entries.mjs --write
node tooling/scripts/generate-ui-changelog-entries.mjs --check
```

`sync-plate-ui` is for downstream user apps consuming the generated JSON. Do not use it to produce upstream Plate changelog entries.

### 5. Style

Use imperative voice:

- `Add support for X`
- `Fix Y behavior`
- `Remove deprecated Z`

Do not use:

- `Added ...`
- `We fixed ...`

Keep simple changes to one line:

```md
- Fix `asChild` TypeScript error
- Add `disabled` prop to Button
```

Use code examples only when needed:

```tsx
// Before
editor.api.foo();

// After
editor.tf.foo();
```

Focus on user impact only. No implementation diary.

Prefer this shape:

- one summary sentence
- optional short `**Migration:**` block
- optional before/after example only when migration would be ambiguous

If a sentence would sound stupid in release notes, cut it.

## Template

Simple:

```md
---
"@platejs/utils": patch
---

Fix `isEmpty` not handling void elements correctly
```

API change:

````md
---
"@platejs/core": patch
---

Rename `editor.api.foo` to `editor.tf.foo`

```tsx
// Before
editor.api.foo();

// After
editor.tf.foo();
```
````

Breaking change:

````md
---
'@platejs/basic-nodes': major
---

Remove `SkipMarkPlugin`; functionality is built into core

**Migration:** Remove `SkipMarkPlugin` from your plugin list. Configure marks directly:

```tsx
MyMarkPlugin.configure({
  rules: { selection: { affinity: 'outward' } },
});
```
````

## Red Flags

Before shipping:

- [ ] Used `minor` for `@platejs/slate`, `@platejs/core`, or `platejs`? Change to `patch`
- [ ] Multiple packages in frontmatter? Split files
- [ ] Describes the last commit, working tree, or branch-only API instead of the
      user-visible delta from `main`? Rewrite it
- [ ] Claims an API was removed or needs migration without proving that API
      exists on `main`? Delete that claim
- [ ] Past tense verbs? Fix them
- [ ] Multiple paragraphs? Condense
- [ ] Too much explanation? Cut it
- [ ] API change without before/after? Add one

## Registry Changelog

For `apps/www/src/registry` changes, use the `registry-changelog` skill. Do not
duplicate its schema here.

