From fbdb291d3cf314562b117ff2b0164023887a112f Mon Sep 17 00:00:00 2001 From: "fern-api[bot]" <115122769+fern-api[bot]@users.noreply.github.com> Date: Mon, 29 Jun 2026 19:55:15 +0000 Subject: [PATCH 1/2] Add configuration, publishing, and retries docs for CLI generator --- fern/products/cli-generator/cli-generator.yml | 6 + fern/products/cli-generator/configuration.mdx | 190 ++++++++++++++++++ fern/products/cli-generator/features.mdx | 26 ++- fern/products/cli-generator/overview.mdx | 2 +- fern/products/cli-generator/publishing.mdx | 104 ++++++++++ 5 files changed, 325 insertions(+), 3 deletions(-) create mode 100644 fern/products/cli-generator/configuration.mdx create mode 100644 fern/products/cli-generator/publishing.mdx diff --git a/fern/products/cli-generator/cli-generator.yml b/fern/products/cli-generator/cli-generator.yml index d7c49b5163..911465c3f7 100644 --- a/fern/products/cli-generator/cli-generator.yml +++ b/fern/products/cli-generator/cli-generator.yml @@ -7,6 +7,12 @@ navigation: - page: Features path: ./features.mdx slug: features + - page: Configuration + path: ./configuration.mdx + slug: configuration + - page: Publishing + path: ./publishing.mdx + slug: publishing - page: Authentication path: ./authentication.mdx slug: authentication diff --git a/fern/products/cli-generator/configuration.mdx b/fern/products/cli-generator/configuration.mdx new file mode 100644 index 0000000000..f10b9d9d71 --- /dev/null +++ b/fern/products/cli-generator/configuration.mdx @@ -0,0 +1,190 @@ +--- +title: Configuration +description: Configure CLI generation in generators.yml with generator-specific options, output targets, GitHub integration, and shared settings. +availability: beta +--- + + +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`. The configuration has two layers: generator-specific options under `config`, and shared options (`output`, `github`, `audiences`, `metadata`, `smart-casing`) that work the same way as for [SDK generators](/learn/sdks/reference/generators-yml). + +```yaml title="generators.yml" {6-8} +groups: + cli: + generators: + - name: fern-cli-generator + version: 0.6.1 + config: + binaryName: my-cli + customCommands: true + github: + repository: my-org/my-cli + mode: pull-request +``` + +## Generator-specific options + + +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. + +```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`) + + + +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. + +```yaml title="generators.yml" +config: + customCommands: false +``` + + +## Shared options + +The following options from the [generators.yml reference](/learn/sdks/reference/generators-yml) apply to the CLI generator identically to SDK generators. + +### `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`. + +```yaml title="generators.yml" +groups: + cli: + generators: + - name: fern-cli-generator + version: 0.6.1 + 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](/learn/cli-generator/get-started/publishing) 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. | + +### `output` + +Configures where to publish the generated CLI. The CLI generator supports `npm` and `local-file-system` output locations. + + + + +Publish the CLI as an npm package. Users install with `npm install -g @myorg/my-cli` or `npx @myorg/my-cli`. + +```yaml title="generators.yml" +groups: + cli: + generators: + - name: fern-cli-generator + version: 0.6.1 + output: + location: npm + package-name: "@myorg/my-cli" + token: "${NPM_TOKEN}" + config: + binaryName: my-cli +``` + + + +Write the generated Rust project to a local directory for manual building and distribution. + +```yaml title="generators.yml" +groups: + cli: + generators: + - name: fern-cli-generator + version: 0.6.1 + output: + location: local-file-system + path: ../my-cli + config: + binaryName: my-cli +``` + + + +### `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. + +```yaml title="generators.yml" +groups: + cli: + audiences: ["external"] + generators: + - name: fern-cli-generator + version: 0.6.1 + config: + binaryName: my-cli +``` + +### `smart-casing` + +Enables intelligent case conversion that preserves numbers and common programming patterns in generated command and flag names. + +```yaml title="generators.yml" +groups: + cli: + generators: + - name: fern-cli-generator + version: 0.6.1 + smart-casing: true + config: + binaryName: my-cli +``` + +### `metadata` + +Attach package metadata to the generated CLI for use in published artifacts. + +```yaml title="generators.yml" +groups: + cli: + generators: + - name: fern-cli-generator + version: 0.6.1 + metadata: + package-description: "CLI for the Contoso API" + author: "Contoso Inc." + reference-url: "https://docs.contoso.com/cli" + config: + binaryName: contoso +``` + +### `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. + +```yaml title="generators.yml" +groups: + cli: + generators: + - name: fern-cli-generator + version: 0.6.1 + api: + auth: BearerAuth + config: + binaryName: my-cli +``` diff --git a/fern/products/cli-generator/features.mdx b/fern/products/cli-generator/features.mdx index f7d7701751..8eb5348278 100644 --- a/fern/products/cli-generator/features.mdx +++ b/fern/products/cli-generator/features.mdx @@ -1,6 +1,6 @@ --- title: Features -description: Explore the capabilities of Fern's generated CLIs, including output formatting, pagination, dry-run mode, and TLS configuration. +description: Explore the capabilities of Fern's generated CLIs, including output formatting, retries, pagination, dry-run mode, and TLS configuration. availability: beta --- @@ -8,7 +8,7 @@ availability: beta The CLI generator is in early access. [Reach out](https://buildwithfern.com/book-demo?type=cli) to get started. -Generated CLIs ship with a common set of runtime flags and environment variables: output formatting, pagination, dry-run previewing, TLS and proxy configuration, exit codes, and structured logging. APIs with templated server URLs also expose per-variable flags and environment variables. +Generated CLIs ship with a common set of runtime flags and environment variables: output formatting, retries with exponential backoff, pagination, dry-run previewing, TLS and proxy configuration, exit codes, and structured logging. APIs with templated server URLs also expose per-variable flags and environment variables. ## Output formatting @@ -37,6 +37,28 @@ Pass `--dry-run` to validate arguments and preview the HTTP request without send contoso plants get --params '{"plantId": "abc"}' --dry-run ``` +## Retries with backoff + +Failed requests are retried automatically with exponential backoff. A request retries as long as the status code is retryable and the retry limit has not been reached. + +| Setting | Default | +| --- | --- | +| Total attempts | 4 (initial + 3 retries) | +| Base delay | 500 ms | +| Backoff factor | 2x | +| Jitter | 10% | + +Retryable status codes: `408` (Timeout), `429` (Too Many Requests), and `5xx` (server errors). The CLI also honors `Retry-After` headers. + +Only idempotent methods (GET, HEAD, OPTIONS, DELETE, PUT) retry by default. POST and PATCH requests retry only when the endpoint is marked idempotent in the spec. + +Pass `--no-retry` on any command to disable retries for that invocation. + +```bash +# Disable retries for a single request +contoso plants create --json '{"name": "Monstera"}' --no-retry +``` + ## Pagination For endpoints annotated with [`x-fern-pagination`](/learn/api-definitions/openapi/extensions/pagination), the CLI auto-paginates when the `--page-all` flag is set. diff --git a/fern/products/cli-generator/overview.mdx b/fern/products/cli-generator/overview.mdx index 0796146c6f..c0560f4662 100644 --- a/fern/products/cli-generator/overview.mdx +++ b/fern/products/cli-generator/overview.mdx @@ -29,7 +29,7 @@ Building a CLI by hand is a multi-quarter project — commands, auth, pagination Generate a CLI from an OpenAPI spec or a GraphQL introspection schema. -The CLI generator plugs into the same Fern workflow as your Docs and SDKs. When your spec changes, Fern opens a PR against your CLI repo with the generated source. On release, Fern automatically publishes the CLI to npm, Homebrew, and GitHub Releases so your users can install it with their package manager of choice. The CLI stays in sync with your Docs and SDKs, and you never need to write CLI code by hand. For organizations that need to keep generation on their own infrastructure, the generator also supports local generation via Docker. +The CLI generator plugs into the same Fern workflow as your Docs and SDKs. When your spec changes, Fern opens a PR against your CLI repo with the generated source. On release, Fern automatically [publishes](/learn/cli-generator/get-started/publishing) the CLI to npm, Homebrew, and GitHub Releases so your users can install it with their package manager of choice. The CLI stays in sync with your Docs and SDKs, and you never need to write CLI code by hand. For organizations that need to keep generation on their own infrastructure, the generator also supports [local generation](/learn/cli-generator/get-started/local-generation) via Docker. The output is a single statically linked Rust binary. Users drop it onto their PATH and run it. There's no language runtime and no dependencies. diff --git a/fern/products/cli-generator/publishing.mdx b/fern/products/cli-generator/publishing.mdx new file mode 100644 index 0000000000..81b918c6cf --- /dev/null +++ b/fern/products/cli-generator/publishing.mdx @@ -0,0 +1,104 @@ +--- +title: Publishing +description: Distribute generated CLIs via npm, Homebrew, and GitHub Releases with automated cross-platform builds. +availability: beta +--- + + +The CLI generator is in early access. [Reach out](https://buildwithfern.com/book-demo?type=cli) to get started. + + +When the CLI generator outputs to a GitHub repository in `release` mode, Fern produces a CI workflow that builds cross-platform binaries and publishes them to npm, Homebrew, and GitHub Releases. Users install the CLI from whichever channel they prefer. + +## Distribution channels + +| Channel | Install command | Platforms | +| --- | --- | --- | +| npm | `npm install -g @myorg/my-cli` | All (via Node.js wrapper) | +| Homebrew | `brew install myorg/tap/my-cli` | macOS, Linux | +| GitHub Releases | Download binary from release assets | All | + +All channels are populated automatically on each tagged release — no manual publishing steps required. + +## Configuration + +Configure publishing in `generators.yml` by setting the `github` output with `mode: release` and an `output` location for npm: + +```yaml title="generators.yml" +api: + specs: + - openapi: openapi.yml +groups: + cli: + generators: + - name: fern-cli-generator + version: 0.6.1 + github: + repository: my-org/my-cli + mode: release + output: + location: npm + package-name: "@myorg/my-cli" + token: "${NPM_TOKEN}" + config: + binaryName: my-cli +``` + +## How it works + +The generated repository includes: + +1. **Rust source** — the complete CLI project, ready to `cargo build`. +2. **GitHub Actions workflow** (`.github/workflows/ci.yml`) — triggered on tagged releases. Builds native binaries for each target platform, then publishes to the configured channels. +3. **Homebrew formula** (when GitHub releases are enabled) — a tap formula pointing at the release assets. + +### Build targets + +The CI workflow produces statically linked binaries for: + +| Target | OS | Architecture | +| --- | --- | --- | +| `x86_64-unknown-linux-gnu` | Linux | x86_64 | +| `aarch64-unknown-linux-gnu` | Linux | ARM64 | +| `x86_64-apple-darwin` | macOS | Intel | +| `aarch64-apple-darwin` | macOS | Apple Silicon | +| `x86_64-pc-windows-msvc` | Windows | x86_64 | + +### npm publishing + +The npm package wraps the native binary with a Node.js launcher. Platform-specific optional dependencies ensure only the correct binary is downloaded at install time, keeping the install lightweight. + +To configure npm authentication: + +- **Token-based**: Set a repository secret (e.g. `NPM_TOKEN`) and reference it in `generators.yml` as `"${NPM_TOKEN}"`. +- **OIDC-based** (recommended): Set `token: OIDC` for keyless publishing with [npm provenance](https://docs.npmjs.com/generating-provenance-statements). + +```yaml title="generators.yml" +output: + location: npm + package-name: "@myorg/my-cli" + token: OIDC +``` + +## Releasing a new version + +With `github.mode: release`, each time your API definition changes and you run `fern generate`, Fern commits the updated source to your CLI repository and tags a new release. The CI workflow triggers automatically, building and publishing the new version. + +For `pull-request` mode, merge the PR and manually create a GitHub release to trigger the publish workflow. + +## Install instructions for users + +After publishing, direct users to install with their preferred method: + +```bash +# npm (all platforms) +npm install -g @myorg/my-cli + +# Homebrew (macOS / Linux) +brew install myorg/tap/my-cli + +# Direct download (any platform) +# Download the appropriate binary from GitHub Releases +curl -fsSL https://github.com/my-org/my-cli/releases/latest/download/my-cli-x86_64-linux -o my-cli +chmod +x my-cli +``` From 6717ea4e69447992e0c334c24a90a99d67381137 Mon Sep 17 00:00:00 2001 From: "fern-api[bot]" <115122769+fern-api[bot]@users.noreply.github.com> Date: Mon, 29 Jun 2026 20:31:26 +0000 Subject: [PATCH 2/2] Restructure publishing page with steps, mark as hidden, remove links from non-hidden pages --- fern/products/cli-generator/cli-generator.yml | 1 + fern/products/cli-generator/configuration.mdx | 2 +- fern/products/cli-generator/overview.mdx | 2 +- fern/products/cli-generator/publishing.mdx | 223 +++++++++++++++--- 4 files changed, 188 insertions(+), 40 deletions(-) diff --git a/fern/products/cli-generator/cli-generator.yml b/fern/products/cli-generator/cli-generator.yml index 911465c3f7..64d334cc62 100644 --- a/fern/products/cli-generator/cli-generator.yml +++ b/fern/products/cli-generator/cli-generator.yml @@ -13,6 +13,7 @@ navigation: - page: Publishing path: ./publishing.mdx slug: publishing + hidden: true - page: Authentication path: ./authentication.mdx slug: authentication diff --git a/fern/products/cli-generator/configuration.mdx b/fern/products/cli-generator/configuration.mdx index f10b9d9d71..3e0bbb4580 100644 --- a/fern/products/cli-generator/configuration.mdx +++ b/fern/products/cli-generator/configuration.mdx @@ -79,7 +79,7 @@ groups: | Mode | Behavior | | --- | --- | -| `release` | Commits to the default branch and tags a new release. Triggers CI workflows that build and [publish](/learn/cli-generator/get-started/publishing) the binary. | +| `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. | diff --git a/fern/products/cli-generator/overview.mdx b/fern/products/cli-generator/overview.mdx index c0560f4662..0796146c6f 100644 --- a/fern/products/cli-generator/overview.mdx +++ b/fern/products/cli-generator/overview.mdx @@ -29,7 +29,7 @@ Building a CLI by hand is a multi-quarter project — commands, auth, pagination Generate a CLI from an OpenAPI spec or a GraphQL introspection schema. -The CLI generator plugs into the same Fern workflow as your Docs and SDKs. When your spec changes, Fern opens a PR against your CLI repo with the generated source. On release, Fern automatically [publishes](/learn/cli-generator/get-started/publishing) the CLI to npm, Homebrew, and GitHub Releases so your users can install it with their package manager of choice. The CLI stays in sync with your Docs and SDKs, and you never need to write CLI code by hand. For organizations that need to keep generation on their own infrastructure, the generator also supports [local generation](/learn/cli-generator/get-started/local-generation) via Docker. +The CLI generator plugs into the same Fern workflow as your Docs and SDKs. When your spec changes, Fern opens a PR against your CLI repo with the generated source. On release, Fern automatically publishes the CLI to npm, Homebrew, and GitHub Releases so your users can install it with their package manager of choice. The CLI stays in sync with your Docs and SDKs, and you never need to write CLI code by hand. For organizations that need to keep generation on their own infrastructure, the generator also supports local generation via Docker. The output is a single statically linked Rust binary. Users drop it onto their PATH and run it. There's no language runtime and no dependencies. diff --git a/fern/products/cli-generator/publishing.mdx b/fern/products/cli-generator/publishing.mdx index 81b918c6cf..84b3c2171b 100644 --- a/fern/products/cli-generator/publishing.mdx +++ b/fern/products/cli-generator/publishing.mdx @@ -1,6 +1,6 @@ --- title: Publishing -description: Distribute generated CLIs via npm, Homebrew, and GitHub Releases with automated cross-platform builds. +description: Publish your generated CLI to npm, Homebrew, and GitHub Releases with automated cross-platform builds. availability: beta --- @@ -8,7 +8,14 @@ availability: beta The CLI generator is in early access. [Reach out](https://buildwithfern.com/book-demo?type=cli) to get started. -When the CLI generator outputs to a GitHub repository in `release` mode, Fern produces a CI workflow that builds cross-platform binaries and publishes them to npm, Homebrew, and GitHub Releases. Users install the CLI from whichever channel they prefer. +Publish your generated CLI to npm, Homebrew, and GitHub Releases. After following the steps on this page, each tagged release builds cross-platform binaries and publishes them automatically. + + +This page assumes that you have: + +* An initialized `fern` folder with `generators.yml` configured for the CLI generator. See [Quickstart](/learn/cli-generator/get-started/quickstart). +* A GitHub repository for the generated CLI source. + ## Distribution channels @@ -18,41 +25,202 @@ When the CLI generator outputs to a GitHub repository in `release` mode, Fern pr | Homebrew | `brew install myorg/tap/my-cli` | macOS, Linux | | GitHub Releases | Download binary from release assets | All | -All channels are populated automatically on each tagged release — no manual publishing steps required. +## Configure output location + + + + + +In the `group` for your CLI, set the output location to `npm`: + +```yaml title="generators.yml" {7-8} +groups: + cli: + generators: + - name: fern-cli-generator + version: 0.6.1 + output: + location: npm + config: + binaryName: my-cli +``` + + + + + +The package name must be unique in the npm registry. + +```yaml title="generators.yml" {9} +groups: + cli: + generators: + - name: fern-cli-generator + version: 0.6.1 + output: + location: npm + package-name: "@myorg/my-cli" + config: + binaryName: my-cli +``` + + + + + +## Configure GitHub publishing + +Fern publishes your CLI via GitHub Actions. Configure your GitHub repository and publishing mode: + +```yaml title="generators.yml" {10-12} +groups: + cli: + generators: + - name: fern-cli-generator + version: 0.6.1 + output: + location: npm + package-name: "@myorg/my-cli" + config: + binaryName: my-cli + github: + repository: my-org/my-cli + mode: release +``` + +| Mode | Behavior | +| --- | --- | +| `release` | Commits to the default branch and tags a release. The CI workflow builds binaries and publishes automatically. | +| `pull-request` | Opens a PR with generated source for review. Merge the PR and create a GitHub release to trigger publishing. | + +## Configure authentication + +Choose how to authenticate with npm when publishing. + + + -## Configuration +OIDC-based publishing (trusted publishing) is the most secure option. npm trusts your GitHub repository to publish directly — no tokens to manage. -Configure publishing in `generators.yml` by setting the `github` output with `mode: release` and an `output` location for npm: + -```yaml title="generators.yml" -api: - specs: - - openapi: openapi.yml + + +Set `token: OIDC` in the `output` section: + +```yaml title="generators.yml" {9} groups: cli: generators: - name: fern-cli-generator version: 0.6.1 + output: + location: npm + package-name: "@myorg/my-cli" + token: OIDC + config: + binaryName: my-cli github: repository: my-org/my-cli mode: release +``` + + + + + +Generate the CLI to create the GitHub Actions workflow with OIDC configuration: + +```bash +fern generate --group cli +``` + +This creates a `.github/workflows/ci.yml` file configured for OIDC npm publishing. + + + + + +Configure trusted publishing on npmjs.com: + +1. Navigate to your package settings on npmjs.com +1. Find the **Trusted Publisher** section and click **Add trusted publisher** +1. Select **GitHub Actions** as your provider +1. Fill in: + - **Organization or user**: Your GitHub username or organization + - **Repository**: Your CLI repository name (e.g. `my-cli`) + - **Workflow filename**: `ci.yml` + - **Environment name**: Leave blank + +For details, see npm's [trusted publishing documentation](https://docs.npmjs.com/trusted-publishers). + + + + + + + + + + + + + +1. Log into [npmjs.com](https://www.npmjs.com/) +1. Click your profile picture and select **Access Tokens** +1. Click **Generate New Token** and choose **Automation** type +1. Save your token securely + + + + + +Set `token: ${NPM_TOKEN}` in the `output` section: + +```yaml title="generators.yml" {9} +groups: + cli: + generators: + - name: fern-cli-generator + version: 0.6.1 output: location: npm package-name: "@myorg/my-cli" - token: "${NPM_TOKEN}" + token: ${NPM_TOKEN} config: binaryName: my-cli + github: + repository: my-org/my-cli + mode: release ``` -## How it works + + + + +1. Open your CLI repository on GitHub and go to **Settings** +1. Navigate to **Secrets and variables** > **Actions** +1. Click **New repository secret** +1. Name it `NPM_TOKEN` and paste your npm token +1. Click **Add secret** -The generated repository includes: + -1. **Rust source** — the complete CLI project, ready to `cargo build`. -2. **GitHub Actions workflow** (`.github/workflows/ci.yml`) — triggered on tagged releases. Builds native binaries for each target platform, then publishes to the configured channels. -3. **Homebrew formula** (when GitHub releases are enabled) — a tap formula pointing at the release assets. + -### Build targets + + + + +## Publish your CLI + +Your CLI publishes automatically when you create a GitHub release with a version tag: + +1. Run `fern generate --group cli` to push updated source to your CLI repository +1. Create a GitHub release with a version tag (e.g. `v1.0.0`) +1. The CI workflow builds binaries for all platforms and publishes to npm, Homebrew, and GitHub Releases + +## Build targets The CI workflow produces statically linked binaries for: @@ -64,27 +232,7 @@ The CI workflow produces statically linked binaries for: | `aarch64-apple-darwin` | macOS | Apple Silicon | | `x86_64-pc-windows-msvc` | Windows | x86_64 | -### npm publishing - -The npm package wraps the native binary with a Node.js launcher. Platform-specific optional dependencies ensure only the correct binary is downloaded at install time, keeping the install lightweight. - -To configure npm authentication: - -- **Token-based**: Set a repository secret (e.g. `NPM_TOKEN`) and reference it in `generators.yml` as `"${NPM_TOKEN}"`. -- **OIDC-based** (recommended): Set `token: OIDC` for keyless publishing with [npm provenance](https://docs.npmjs.com/generating-provenance-statements). - -```yaml title="generators.yml" -output: - location: npm - package-name: "@myorg/my-cli" - token: OIDC -``` - -## Releasing a new version - -With `github.mode: release`, each time your API definition changes and you run `fern generate`, Fern commits the updated source to your CLI repository and tags a new release. The CI workflow triggers automatically, building and publishing the new version. - -For `pull-request` mode, merge the PR and manually create a GitHub release to trigger the publish workflow. +The npm package wraps the native binary with a Node.js launcher. Platform-specific optional dependencies ensure only the correct binary downloads at install time. ## Install instructions for users @@ -98,7 +246,6 @@ npm install -g @myorg/my-cli brew install myorg/tap/my-cli # Direct download (any platform) -# Download the appropriate binary from GitHub Releases curl -fsSL https://github.com/my-org/my-cli/releases/latest/download/my-cli-x86_64-linux -o my-cli chmod +x my-cli ```