---
description: Command syntax, release groups, exact plans, recovery, and exit behavior for the Verso CLI.
---

# CLI reference

## `verso [OPTIONS] [COMMAND]`

Running without a subcommand plans or executes a full release. Global options may appear before or
after a subcommand.

| Option                 | Default      | Meaning                                                              |
| ---------------------- | ------------ | -------------------------------------------------------------------- |
| `--dry-run`            | `false`      | Render an exact plan without writes, hooks, or mutating Git commands |
| `--json`               | `false`      | Render a dry-run, doctor report, or transaction status as JSON       |
| `--version <SEMVER>`   | interactive  | Use an exact valid SemVer target for a release or `bump`             |
| `--config <PATH>`      | `verso.toml` | Use another group config; its parent becomes the release root        |
| `--group <NAME>`       | -            | Select `verso.NAME.toml`; conflicts with `--config`                  |
| `--yes`                | `false`      | Accept release or bump confirmations; does not select a version      |
| `-V`, `--tool-version` | -            | Print the installed Verso version and exit                           |
| `--help`               | -            | Print command help                                                   |

```sh
verso --dry-run --version 2.0.0-rc.0
verso --group core --version 2.0.0 --yes
verso doctor --group core --json
verso --tool-version
```

`--json` requires `--dry-run` for a release or bump. `doctor --json` and `status --json` do not need
`--dry-run`.

### Interactive release version selection

Without `--version`, a full release offers patch, minor, major, alpha, beta, rc, and custom SemVer
choices. When the current version is a prerelease, the corresponding stable version is offered too.

Alpha, beta, and rc selections ask for a patch, minor, major, or custom base. Repeating the same
channel on the same base increments its numeric suffix; changing the channel or base starts at `.0`.
For example, selecting beta + minor from `1.3.0-beta.0` yields `1.3.0-beta.1`.

An exact target may be equal to or lower than the current version. That requires a separate
default-no confirmation unless `--yes` is set. When stdin or stdout is not a terminal, the same
choices use plain-text prompts.

<Callout variant="warning" title="--yes also accepts a non-increasing version">
  Automation must choose and validate its target version before invoking Verso. `--yes` accepts the
  additional confirmation for a target equal to or lower than the current version.
</Callout>

### Exact dry-run plans

Dry-run performs the real planning transformation in memory. Text output includes the operation,
release group, changed-file tree, and the actual full-file before/after diff for every planned
change. It executes no hooks, writes no files, and runs no mutating Git command.

JSON adds a `fileChanges` array whose entries contain `path`, `kind`, `before`, `after`, and `diff`.
The complete object contains `operation`, `group`, `currentVersion`, `targetVersion`, `packageFiles`,
`extraVersionFiles`, `versionFiles`, `changelogFile`, `fileChanges`, `commitMessage`, `tagName`,
`hooks`, `warnings`, and `gitCommands`. Paths are relative to the release root. Release Git commands
use tag-object, commit-OID, and upstream placeholders rather than contacting a remote; bump plans
have no changelog or Git commands.

## `verso bump`

```sh
verso bump patch
verso bump minor --dry-run
verso bump major --group core
verso bump --version 2.0.0
```

Exactly one bump level (`patch`, `minor`, or `major`) or `--version <SEMVER>` is required. The command
updates discovered package manifests, configured Cargo manifests, and matching entries in the nearest
Cargo lockfiles. It does not update the changelog, create a commit or tag, or push. Only
`before_version` and `after_version` hooks apply.

## Release groups

One config is one release group, and every member of that group must start at the same version.
`--group core` is shorthand for `--config verso.core.toml`; the two options are mutually exclusive.
Use separate configs for groups that version independently, and run one group per command.

Group names must start with an ASCII letter or digit and may otherwise contain ASCII letters, digits,
`-`, and `_`.

## `verso init`

```sh
verso [--config <PATH>] init [--single | --workspace] [--force]
```

| Option        | Meaning                                |
| ------------- | -------------------------------------- |
| `--single`    | Write a single-package starter         |
| `--workspace` | Write a `packages/*` workspace starter |
| `--force`     | Replace an existing config file        |

Without a mode, only `packages/*/package.json` is used for detection. Parent directories for a
custom config path are created as needed.

## `verso doctor`

```sh
verso [--config <PATH> | --group <NAME>] doctor [--json]
```

The report checks release root resolution, config, discovered packages, current and consistent
versions, configured Cargo versions, changelog writability, and Git upstream readiness. Text output
uses `PASS` / `FAIL`; JSON returns:

```json
{
  "ok": true,
  "checks": [{ "name": "config", "status": "pass", "message": "..." }],
  "packageCount": 3,
  "currentVersion": "1.4.0"
}
```

A failed doctor report exits with status 1 even when JSON was written successfully.

## Transaction recovery

```sh
verso [--config <PATH> | --group <NAME>] status [--json]
verso [--config <PATH> | --group <NAME>] resume [--retry-hook | --skip-hook]
verso [--config <PATH> | --group <NAME>] abort [--force]
```

`status` shows the active operation, group, stage, version pair, interrupted hook, and changed-file
count. With `--json`, it also reports `canAbort`, `canForceAbort`, `pushStarted`, and `pushFailed`;
when no transaction exists, it returns `{ "active": false }`.

`resume` verifies the persisted plan, skips completed work, and continues from the recorded stage.
If a hook was interrupted, inspect its side effects and choose exactly one of `--retry-hook` or
`--skip-hook`.

`abort` rolls back only state still owned by the transaction and refuses to overwrite later edits.
After manual recovery, `abort --force` discards only the journal and leaves files and refs unchanged.

<Callout variant="danger" title="After push starts, resume only">
  A remote result may be unknown, so Verso disables abort as soon as push starts. Inspect the
  remote, then use `resume`; do not use `abort --force` as a rollback.
</Callout>

See [Release workflow](/release-workflow/) for the exact stage model, reconciliation rules, and
failure matrix.

Verso exits with 0 on success and 1 for validation, cancellation, hook, Git, transaction, or launch
errors.
