CLI reference

The complete molt command surface: every verb, its flags, its exit codes, and the cross-cutting rules that apply to all of them.

You install the distribution molt-cli and type the command molt. See Installation for why the two names differ.

Command surface at a glance

CommandWhat it doesReference
molt initScaffold config and the .changeset/ directory; detect the ecosystem backend and workspace layout.molt init
molt addRecord a changeset: affected packages, bump types, and a summary. The default command -- bare molt runs this.molt add
molt versionConsume pending changesets: bump versions, propagate to dependents, rewrite pins, write changelogs, update the lockfile.molt version
molt statusReport pending changesets and the projected release, as text or JSON. Doubles as a CI gate.molt status
molt publishBuild, then upload changed packages to PyPI via OIDC Trusted Publishing, in dependency order.molt publish
molt publish-planPrint or emit the resolved publish plan without uploading anything.molt publish
molt buildBuild sdist and wheel artifacts for the packages a plan will publish. (The "pack" stage.)molt build
molt yankCheck a released version and print the steps to yank it on PyPI (PEP 592). Read-only -- PyPI has no yank API, so you finish it in the browser.molt yank
molt git-tagCreate annotated git tags for released packages.molt git-tag
molt prePrerelease control. Molt has no persistent pre-mode: prereleases are the stateless molt version --pre flag.Prerelease control

The default command

molt with no command word runs molt add. An option that belongs to add also works with no command word:

molt              # same as: molt add
molt --open       # same as: molt add --open

An explicit command is never overridden -- molt version runs version, not add.

Global options

These options are accepted by every command (subject to the command actually having prompts, mutations, or machine-readable output to control).

OptionTypeDefaultDescription
--non-interactive, --yesflagoffNever block on a prompt. Each prompt resolves to its documented default, or the command exits non-zero naming the missing input. Required for CI, Dependabot, Renovate, and codegen.
--dry-runflagoffOn any mutating command (add, version, publish, git-tag, build), print the plan the command would execute and write nothing. (yank has none: it never mutates, so every run is already a dry run.) See Dry runs and plans.
--output jsonstringhuman-readableWhere supported (status, publish-plan), emit the plan as a JSON document to stdout instead of the rendered view. See Machine-readable output.
--cwd <path>pathcurrent directoryDirectory to run in. Root discovery walks up from here to the workspace root.
--versionflag--Print the bare version string (for example 0.1.0) and exit 0. No banner, no prefix.
-h, --helpflag--Show help for the program or a command and exit 0.

The startup banner (molt v<version>, prefixed with a butterfly glyph) prints once before a matched command's output. It is not printed for --help or --version. On a Windows console that cannot encode the glyph, the banner degrades to plain text rather than raising an error.

-v is not a global alias for --version. On molt status, -v means --verbose. Use the long --version form for the version string.

Machine-readable output

Molt produces a machine-readable plan object on every mutating command, and structured output on read commands:

  • molt status and molt publish-plan accept --output json to print the plan as a JSON document to stdout.
  • molt publish and molt git-tag accept --output <file> to write an NDJSON event stream -- one {"type":"git-tag", ...} object per line -- to a file.
  • The MOLT_OUTPUT environment variable back-fills --output when the flag is not passed, so CI can set it once for the whole pipeline.

Option-normalization rules

The same argument-handling rules apply across every command:

  • Repeated scalar options: last wins. --since main --since next resolves to next, with no warning.
  • Repeatable list options always yield a list, even for a single occurrence. This covers --major, --minor, --patch, --package, and --ignore.
  • Numeric-looking values stay strings. --snapshot-name 123 is the string "123", so version and tag names that look numeric are never coerced to integers.
  • Arguments after a bare -- are dropped. There is no pass-through.
  • --snapshot takes an optional value through a small, documented divergence from changesets. Because the parser cannot bind a space-separated optional value, use --snapshot (unnamed), --snapshot=<name>, or --snapshot-name <name>. The space form --snapshot <name> is rejected with guidance. See molt version.

Exit-code contract

SituationExit code
Command succeeds0
Prompt cancelled with Ctrl-C0 (a deliberate, documented divergence from POSIX 130)
Any validation failure or user-facing error1
molt status finds changed packages but no changesets (CI gate)1
molt status when nothing relevant changed (or only ignored, private, or unmatched files)0
molt version when there are no unreleased changesets1
molt publish when there is nothing to publish0
A command whose implementation has not yet landednon-zero
Unexpected internal error1

On an unexpected internal error, molt prints a pre-filled issue-report URL that includes the CLI version and the Python version, with the working directory redacted to <cwd>, then exits 1. Any other uncaught exception prints a traceback and exits 1. molt never lets a bare traceback escape as the program's only output.

See also