Configuration reference

Beta
View as Markdown
Early access

The CLI generator is in early access. Reach out to get started.

Configure the CLI generator in generators.yml. Options nested under config are specific to the CLI generator. The rest (output, github, audiences, smart-casing, metadata, api) behave the same way as for SDK generators.

generators.yml
1groups:
2 cli:
3 generators:
4 - name: fern-cli-generator
5 version: 0.38.4
6 config:
7 binaryName: my-cli
8 customCommands: true
9 github:
10 repository: my-org/my-cli
11 mode: pull-request

config options

binaryName
string

Name of the compiled binary. Determines the executable filename, the Cargo [[bin]] target name, and the environment-variable prefix used for TLS, proxy, and logging settings.

When omitted, the generator derives the name from the API definition’s display name (kebab-cased). Multi-spec workspaces must set this field explicitly — there is no sensible auto-derivation when multiple specs are present.

generators.yml
1config:
2 binaryName: contoso

The binary name contoso produces:

  • Executable: contoso
  • Env-var prefix: CONTOSO (e.g. CONTOSO_CA_BUNDLE, CONTOSO_LOG)
customCommands
booleanDefaults to true

Controls whether the generator produces the custom command infrastructure alongside the CLI binary. When enabled, the output includes:

  • A <binaryName>-types library crate (typed serde structs)
  • A <binaryName>-sdk library crate (HTTP client accessible via ctx.client())
  • Scaffolding files for user-authored command handlers

Set to false to produce a spec-only CLI with no custom command support.

generators.yml
1config:
2 customCommands: false
userAgentSuffixFlag
stringDefaults to user-agent-suffix

Renames the global flag (and its derived environment variable) that a downstream consumer uses to append a product token to the generated CLI’s User-Agent. Provide the flag’s long name without the leading --. It must be a kebab identifier matching ^[a-z][a-z0-9-]*$ and can’t collide with a built-in flag name.

Any kebab identifier is accepted except the CLI’s built-in flag names (params, output, json, format, dry-run, base-url, page-all, page-limit, page-delay, no-pager, no-extract, no-retry, no-stream, quiet, query, help, debug, schema). The default user-agent-suffix exposes --user-agent-suffix and <NAME>_USER_AGENT_SUFFIX. For example, setting via exposes --via and <NAME>_VIA instead (the environment variable is <NAME>_ followed by the flag uppercased with hyphens converted to underscores):

generators.yml
1config:
2 userAgentSuffixFlag: via

A consumer of the generated contoso CLI then appends its product token with the renamed flag:

$contoso plants list --via "partner-app/3.1"
$# sends User-Agent: contoso-cli/1.4.0 partner-app/3.1
generateWireTests
booleanDefaults to false

Generates a wiremock-based integration test suite alongside the CLI. When enabled, generation emits a wire_test.rs harness and a wire-test-cases.json manifest with one case per endpoint example. Each test starts an in-process mock server, drives the compiled binary, and asserts the command hit the expected method and path and rendered the mocked response. The generated CI runs the suite with cargo test.

Only commands derived from the API spec are covered; custom commands aren’t.

generators.yml
1config:
2 generateWireTests: true
splitTypeCrates
booleanDefaults to false

Splits the generated types into one crate per API, plus a shared core crate for types that more than one API references, nested inside <binaryName>-types/crates/. By default, every generated model lands in a single <binaryName>-types crate.

Enable it for workspaces with many specs, where that single crate is one rustc compilation unit large enough to exhaust the memory of a standard CI runner and get cargo build killed. Splitting also shortens builds, because the per-API crates compile in parallel and cache independently. <binaryName>-types remains as a facade that re-exports everything, so imports such as use plant_types::Plant; keep resolving and custom command handlers need no changes. The shipped artifact is the same either way: one binary with every spec embedded.

generators.yml
1config:
2 binaryName: plant
3 splitTypeCrates: true
packageIdentity
object

Sets the Cargo [package] metadata of the generated crate. Use packageIdentity to publish the crate under your own name, license, repository, and authors instead of Fern’s.

generators.yml
1config:
2 binaryName: plant
3 packageIdentity:
4 name: plant-cli
5 description: Command-line interface for the Plant API.
6 license: MIT
7 repository: https://github.com/garden/plant-cli
8 homepage: https://example.com
9 authors: ["Plants <support@garden-plants.com>"]
10 keywords: ["plants", "cli"]
packageIdentity.name
string

Crate name. Must be a valid cargo crate name: it starts with a letter and contains only letters, digits, -, and _. Invalid values fail at generation time with a config error instead of surfacing later as a manifest error during cargo build. The generator renames the matching Cargo.lock entry in the same pass, so cargo build --locked still resolves the workspace member.

packageIdentity.description
string

Short crate description shown on crates.io.

packageIdentity.license
string

SPDX license expression, such as Apache-2.0.

packageIdentity.repository
string

URL of the crate’s source repository.

packageIdentity.homepage
string

URL of the project homepage.

packageIdentity.authors
array of strings

Crate authors, in Cargo’s Name <email> form.

packageIdentity.keywords
array of strings

Keywords for crates.io search.

distribution
object

Adds Homebrew and Scoop publishing on top of the GitHub Release archives every generated CLI already ships. Both channels install from a tagged release, so distribution is honored only when the generator delivers to a GitHub repository through the github block. Enabling a channel adds a publish job to the release workflow and the matching install command to the generated README. Each job pushes to a public tap or bucket repository you create, authenticating with either a personal access token per channel or a GitHub App whose credentials you store as repository secrets.

generators.yml
1config:
2 binaryName: plant
3 distribution:
4 homebrew:
5 tap: garden/homebrew-tap
6 formula: plant
7 scoop:
8 bucket: garden/scoop-bucket
distribution.githubApp
object

GitHub App that the Homebrew and Scoop publish jobs use to mint a short-lived installation token at release time, instead of reading a long-lived personal access token. Declared once for both channels; a tap and a bucket under different accounts each need the App installed on their own account, since every job requests a token for the owner of the repository it pushes to. A channel’s tokenEnvironmentVariable takes precedence over githubApp.

distribution.githubApp.appIdSecret
stringRequired

Name of the GitHub Actions secret holding the App’s App ID or Client ID.

distribution.githubApp.privateKeySecret
stringRequired

Name of the GitHub Actions secret holding the entire contents of the App’s private key .pem file, line breaks included.

distribution.homebrew.tap
stringRequired

Tap repository as <owner>/<repo>, such as garden/homebrew-tap. The repository must already exist and be public.

distribution.homebrew.formula
string

Formula name, which is also the .rb filename brew install <tap>/<formula> resolves against. Must start with a lowercase letter and contain only [a-z0-9-]. Defaults to binaryName.

distribution.homebrew.tokenEnvironmentVariable
stringDefaults to HOMEBREW_TAP_TOKEN

Name of the GitHub Actions secret holding a token with write access to the tap repository. The workflow’s built-in GITHUB_TOKEN is scoped to the CLI repository and is rejected here.

distribution.scoop.bucket
stringRequired

Bucket repository as <owner>/<repo>, such as garden/scoop-bucket. The repository must already exist and be public. The generated manifest declares a 64bit architecture only.

distribution.scoop.tokenEnvironmentVariable
stringDefaults to SCOOP_BUCKET_TOKEN

Name of the GitHub Actions secret holding a token with write access to the bucket repository.

Publishing & delivery

output

Configures where to publish the generated CLI. The CLI generator supports npm and local-file-system output locations; binaries also reach users through the GitHub Release that each tag produces, plus the opt-in Homebrew and Scoop channels configured under distribution. The publishing workflow covers OIDC auth, CI builds, and tap and bucket setup, and self-hosted generation covers Docker-based generation on your own machine.

Publish the CLI as an npm package. Users install with npm install -g @myorg/my-cli or npx @myorg/my-cli.

generators.yml
1groups:
2 cli:
3 generators:
4 - name: fern-cli-generator
5 version: 0.38.4
6 output:
7 location: npm
8 package-name: "@myorg/my-cli"
9 token: "${NPM_TOKEN}"
10 config:
11 binaryName: my-cli

Write the generated Rust project to a local directory for manual building and distribution.

generators.yml
1groups:
2 cli:
3 generators:
4 - name: fern-cli-generator
5 version: 0.38.4
6 output:
7 location: local-file-system
8 path: ../my-cli
9 config:
10 binaryName: my-cli

github

Specifies how generated CLI code is delivered to your repository. Supports the same modes as SDKs: release, pull-request, and push.

generators.yml
1groups:
2 cli:
3 generators:
4 - name: fern-cli-generator
5 version: 0.38.4
6 config:
7 binaryName: my-cli
8 github:
9 repository: my-org/my-cli
10 mode: release
ModeBehavior
releaseCommits to the default branch and tags a new release. Triggers CI workflows that build and publish the binary.
pull-requestOpens a PR with the generated source for review before merging.
pushPushes directly to the specified branch. Requires branch field.

Command generation

audiences

Filter which API endpoints are included in the generated CLI based on audience tags. Only endpoints tagged with the specified audiences in your API spec (via x-fern-audiences) produce commands. Without this filter, all endpoints generate commands.

generators.yml
1groups:
2 cli:
3 audiences: ["external"]
4 generators:
5 - name: fern-cli-generator
6 version: 0.38.4
7 config:
8 binaryName: my-cli

smart-casing

Enables intelligent case conversion that preserves numbers and common programming patterns in generated command and flag names.

generators.yml
1groups:
2 cli:
3 generators:
4 - name: fern-cli-generator
5 version: 0.38.4
6 smart-casing: true
7 config:
8 binaryName: my-cli

api

Override authentication settings at the generator level. This uses the same schema as the SDK generator-level api.auth to control which auth schemes the CLI uses.

generators.yml
1groups:
2 cli:
3 generators:
4 - name: fern-cli-generator
5 version: 0.38.4
6 api:
7 auth: BearerAuth
8 config:
9 binaryName: my-cli

metadata

Attach package metadata to the generated CLI for use in published artifacts.

generators.yml
1groups:
2 cli:
3 generators:
4 - name: fern-cli-generator
5 version: 0.38.4
6 metadata:
7 package-description: "CLI for the Contoso API"
8 author: "Contoso Inc."
9 reference-url: "https://docs.contoso.com/cli"
10 config:
11 binaryName: contoso