> For clean Markdown content of this page, append .md to this URL. For the complete documentation index, see https://buildwithfern.com/learn/llms.txt. # Configuration reference > Configure CLI generation in generators.yml with generator-specific options, output targets, GitHub integration, and shared settings. #### Early access The CLI generator is in early access. [Reach out](https://buildwithfern.com/book-demo?type=cli) 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](/learn/sdks/reference/generators-yml). **`generators.yml`** ```yaml title="generators.yml" {6-8} groups: cli: generators: - name: fern-cli-generator version: 0.40.0 config: binaryName: my-cli customCommands: true github: repository: my-org/my-cli 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](/learn/cli-generator/get-started/features#tls-proxies-and-ca-bundles). 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`** ```yaml title="generators.yml" config: binaryName: contoso ``` The binary name `contoso` produces: * Executable: `contoso` * Env-var prefix: `CONTOSO` (e.g. `CONTOSO_CA_BUNDLE`, `CONTOSO_LOG`) --- **`customCommands`** `boolean` — default: true Controls whether the generator produces the custom command infrastructure alongside the CLI binary. When enabled, the output includes: * A `-types` library crate (typed serde structs) * A `-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`** ```yaml title="generators.yml" config: customCommands: false ``` --- **`userAgentSuffixFlag`** `string` — default: 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`](/learn/cli-generator/get-started/features#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 `_USER_AGENT_SUFFIX`. For example, setting `via` exposes `--via` and `_VIA` instead (the environment variable is `_` followed by the flag uppercased with hyphens converted to underscores): **`generators.yml`** ```yaml title="generators.yml" config: userAgentSuffixFlag: via ``` A consumer of the generated `contoso` CLI then appends its product token with the renamed flag: ```bash contoso plants list --via "partner-app/3.1" # sends User-Agent: contoso-cli/1.4.0 partner-app/3.1 ``` --- **`generateWireTests`** `boolean` — default: 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](/learn/cli-generator/get-started/customization) aren't. **`generators.yml`** ```yaml title="generators.yml" config: generateWireTests: true ``` --- **`splitTypeCrates`** `boolean` — default: 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 `-types/crates/`. By default, every generated model lands in a single `-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. `-types` remains as a facade that re-exports everything, so imports such as `use plant_types::Plant;` keep resolving and [custom command](/learn/cli-generator/get-started/customization) handlers need no changes. The shipped artifact is the same either way: one binary with every spec embedded. **`generators.yml`** ```yaml title="generators.yml" config: binaryName: plant 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`** ```yaml title="generators.yml" config: binaryName: plant packageIdentity: name: plant-cli description: Command-line interface for the Plant API. license: MIT repository: https://github.com/garden/plant-cli homepage: https://example.com authors: ["Plants "] 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 ` 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](/learn/cli-generator/get-started/publishing#configure-distribution-channels) you create, authenticating with either a personal access token per channel or a GitHub App whose credentials you store as repository secrets. **`generators.yml`** ```yaml title="generators.yml" config: binaryName: plant distribution: homebrew: tap: garden/homebrew-tap formula: plant scoop: 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](/learn/cli-generator/get-started/publishing#configure-distribution-channels), 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`** `string` — required Name of the GitHub Actions secret holding the App's App ID or Client ID. --- **`distribution.githubApp.privateKeySecret`** `string` — required Name of the GitHub Actions secret holding the entire contents of the App's private key `.pem` file, line breaks included. --- **`distribution.homebrew.tap`** `string` — required Tap repository as `/`, 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 /` resolves against. Must start with a lowercase letter and contain only `[a-z0-9-]`. Defaults to `binaryName`. --- **`distribution.homebrew.tokenEnvironmentVariable`** `string` — default: 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`** `string` — required Bucket repository as `/`, such as `garden/scoop-bucket`. The repository must already exist and be public. The generated manifest declares a `64bit` architecture only. --- **`distribution.scoop.tokenEnvironmentVariable`** `string` — default: 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`](#config-options). The [publishing workflow](/learn/cli-generator/get-started/publishing) covers OIDC auth, CI builds, and tap and bucket setup, and [self-hosted generation](/learn/cli-generator/get-started/local-generation) covers Docker-based generation on your own machine. #### npm Publish the CLI as an npm package. Users install with `npm install -g @myorg/my-cli` or `npx @myorg/my-cli`. **`generators.yml`** ```yaml title="generators.yml" groups: cli: generators: - name: fern-cli-generator version: 0.40.0 output: location: npm package-name: "@myorg/my-cli" token: "${NPM_TOKEN}" config: binaryName: my-cli ``` #### Local file system Write the generated Rust project to a local directory for manual building and distribution. **`generators.yml`** ```yaml title="generators.yml" groups: cli: generators: - name: fern-cli-generator version: 0.40.0 output: location: local-file-system path: ../my-cli config: binaryName: my-cli ``` ### `github` Specifies how generated CLI code is delivered to your repository. Supports the same [modes as SDKs](/learn/sdks/reference/generators-yml#github): `release`, `pull-request`, and `push`. **`generators.yml`** ```yaml title="generators.yml" groups: cli: generators: - name: fern-cli-generator version: 0.40.0 config: binaryName: my-cli github: repository: my-org/my-cli mode: release ``` | Mode | Behavior | | -------------- | -------------------------------------------------------------------------------------------------------------- | | `release` | Commits to the default branch and tags a new release. Triggers CI workflows that build and publish the binary. | | `pull-request` | Opens a PR with the generated source for review before merging. | | `push` | Pushes 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`](/learn/api-definitions/openapi/extensions/audiences)) produce commands. Without this filter, all endpoints generate commands. **`generators.yml`** ```yaml title="generators.yml" groups: cli: audiences: ["external"] generators: - name: fern-cli-generator version: 0.40.0 config: binaryName: my-cli ``` ### `smart-casing` Enables intelligent case conversion that preserves numbers and common programming patterns in generated command and flag names. **`generators.yml`** ```yaml title="generators.yml" groups: cli: generators: - name: fern-cli-generator version: 0.40.0 smart-casing: true config: binaryName: my-cli ``` ### `api` Override authentication settings at the generator level. This uses the same schema as the [SDK generator-level `api.auth`](/learn/sdks/reference/generators-yml#override-api-authentication-settings) to control which auth schemes the CLI uses. **`generators.yml`** ```yaml title="generators.yml" groups: cli: generators: - name: fern-cli-generator version: 0.40.0 api: auth: BearerAuth config: binaryName: my-cli ``` ### `metadata` Attach package metadata to the generated CLI for use in published artifacts. **`generators.yml`** ```yaml title="generators.yml" groups: cli: generators: - name: fern-cli-generator version: 0.40.0 metadata: package-description: "CLI for the Contoso API" author: "Contoso Inc." reference-url: "https://docs.contoso.com/cli" config: binaryName: contoso ``` > Configure CLI generation in generators.yml with generator-specific options, output targets, GitHub integration, and shared settings.