Adding a changeset

molt add records the intent of a change -- which packages it affects, how much, and what the changelog should say -- either through an interactive prompt or fully non-interactively for scripts and bots.

A changeset is a small Markdown file in .changeset/. You commit it in the same pull request as your code, and molt version consumes it at release time. This guide covers both ways to write one. For the file format itself, see Changeset format.

Interactive: molt add

Run it with no arguments:

molt add

What you are asked depends on the shape of your repository.

Single-package repositories

molt skips straight to the bump and the summary:

? What kind of change is this for acme-core? (current version is 1.2.0) (Use arrow keys)
 > patch
   minor
   major
? Please enter a summary for this change (this will be in the changelogs). Fix a race condition in the export writer.

Workspaces

In a workspace, molt first asks which packages changed, then how much. The package list puts the packages that actually changed since your base branch first, so the common case is a couple of keystrokes:

? Which packages would you like to include? (Use arrow keys to move, <space> to
select, <a> to toggle, <i> to invert)
 > o changed packages
   o   acme-core
   o unchanged packages
   o   acme-cli
   o   acme-utils

Then, for the packages you selected, molt asks for the major bumps, then the minor bumps; anything you do not mark as major or minor is patched. You end on the same summary prompt.

If a summary is a breaking change, molt reminds you to spell out what broke, why, and how to migrate -- that text is what your users read.

Submitting an empty summary opens your $EDITOR so you can write a longer entry, including Markdown headings (molt preserves them).

What the prompts do

A few rules are worth knowing before you meet them:

  • The group headings are selectable. changed packages and unchanged packages are rows you can check like any other. Checking a heading selects every package under it, so "everything that changed" is one keystroke. The heading expands when you submit -- it does not tick each member's box as you move, and you cannot check a heading and then uncheck one of its members. Select the members individually if you need that.
  • Only groups that have members are shown. In a repository where nothing changed since your base branch, you get one group, still labelled unchanged packages, so you can see why everything is listed together. If molt cannot work out what changed -- an unfetched base branch in a shallow CI clone, or a typo in base_branch -- it says so and offers that same single group rather than pretending nothing changed.
  • Nothing you skip is asked about twice. After the major and the minor questions, every package you selected and did not mark gets a patch, with no prompt of its own.
  • An empty summary opens your editor. Save and close and molt takes the text; close without saving and molt asks again on the console. molt strips only its own comment from the top of the buffer -- your text, Markdown headings included, comes back exactly as you typed it.
  • Ctrl-C at any question stops cleanly. molt prints Canceled, writes nothing, and exits 0.

The result is a file like this, with a random, human-readable name:

# .changeset/late-mangos-cheer.md
---
"acme-core": minor
"acme-cli": patch
---

Add streaming support to the export API. The CLI now shows a progress bar
for large exports.

Package names are always quoted; the front matter maps each affected package to a bump type; the body is the changelog entry. Commit it with your code.

Non-interactive: flags

Every changeset you can create by hand, you can create without a prompt. This is what lets Dependabot, Renovate, and code generators open a pull request that is already complete.

Pass the package, the bump, and the message directly:

molt add --package acme-core --bump minor --message "Add a --stream flag to the export API."

For several packages in one changeset, repeat the --package / --bump pair (they are matched in order):

molt add \
  --package acme-core --bump minor \
  --package acme-cli  --bump patch \
  --message "Add streaming support and wire it through the CLI."

--bump accepts patch, minor, or major. --message (short -m) supplies the summary; passing it is what makes the command fully non-interactive. Because you name the packages explicitly, this form does no "changed packages" detection and never blocks on a prompt -- safe to run in CI.

Non-interactive: piped JSON

For tools that generate changesets programmatically, pipe a JSON object carrying the same information the file does:

echo '{"releases": {"pip-audit": "patch"}, "summary": "Bump pip-audit for GHSA-xxxx."}' \
  | molt add --stdin

This is the form a dependency bot uses: it opens a PR that bumps a dependency and, in the same PR, pipes a changeset so the change is never released without a changelog entry. The exact schema is documented under molt add.

No release needed

Some changes -- a README fix, a test-only tweak -- should ship no version bump at all. Record that intent explicitly with an empty changeset:

molt add --empty

This writes a changeset with no releases and an optional message. It satisfies the molt status CI gate ("a package changed but no changeset was found") without forcing a release. Use it instead of skipping molt add, so the decision is visible in the pull request.

Where to go next