CliOutput unstable
Formats CLI help and errors as text.
This module turns help documents, CLI errors, grouped errors, and version
information into strings. It does not write those strings to the terminal
itself. It includes the Formatter interface, the formatter service, a layer
for custom formatters, and the default formatter with configurable color
support.
Constructors
defaultFormatter
unstableCreates a default formatter with configurable options.
Signature
declare function defaultFormatter(options?: { colors?: boolean;}): FormatterExample Creating default formatters
import { CliError, CliOutput } from "effect/cli"
// Create a formatter without colors for tests or CI environmentsconst noColorFormatter = CliOutput.defaultFormatter({ colors: false })
// Create a formatter with colors forced onconst colorFormatter = CliOutput.defaultFormatter({ colors: true })
// Auto-detect colors based on terminal support (default behavior)const autoFormatter = CliOutput.defaultFormatter()
const error = new CliError.InvalidValue({ option: "foo", value: "bar", expected: "baz", kind: "flag"})
noColorFormatter.formatError(error).includes("Invalid value") // => truecolorFormatter.formatVersion("my-tool", "1.2.3").includes("my-tool") // => trueautoFormatter.formatVersion("my-tool", "1.2.3").includes("1.2.3") // => trueLayers
Creates a Layer that provides a custom Formatter implementation.
Signature
declare function layer(formatter: Formatter): Layer<never>Example Providing a custom formatter
import { Effect } from "effect"import { CliOutput } from "effect/cli"
// Create a custom formatter without colorsconst noColorFormatter = CliOutput.defaultFormatter({ colors: false })const NoColorLayer = CliOutput.layer(noColorFormatter)
// Create a program that uses the custom formatterconst program = Effect.gen(function*() { const formatter = yield* CliOutput.Formatter return formatter.formatVersion("my-cli", "1.0.0")}).pipe( Effect.provide(NoColorLayer))
await Effect.runPromise(program) // => "my-cli v1.0.0"Measuring
displayWidth
unstableMeasures the number of terminal cells a string occupies.
Details
Uses the same measurement as built-in help and table rendering. ANSI styling
is stripped before measuring graphemes: zero-width graphemes count as 0,
emoji presentation sequences and fullwidth characters as 2, and other
graphemes as 1.
Signature
declare function displayWidth(text: string): numberExample Measuring terminal-cell widths
import { CliOutput } from "effect/cli"
CliOutput.displayWidth("file") // => 4CliOutput.displayWidth("ファイル") // => 8CliOutput.displayWidth("é") // => 1CliOutput.displayWidth("1️⃣") // => 2CliOutput.displayWidth("\u001B[1mbold\u001B[0m") // => 4Models
Defines the service interface for formatting CLI output including help, errors, and version info. This allows customization of output formatting, including color support.
Signature
interface Formatter { readonly formatCliError: (error: CliError) => string; readonly formatError: (error: CliError) => string; readonly formatErrors: (errors: readonly Array<CliError>) => string; readonly formatHelpDoc: (doc: HelpDoc) => string; readonly formatVersion: (name: string, version: string) => string;}Example Customizing CLI output formatting
import { Effect } from "effect"import { CliOutput } from "effect/cli"
// Create a custom formatter implementationconst customFormatter: CliOutput.Formatter = { formatHelpDoc: (doc) => `Custom Help: ${doc.usage}`, formatCliError: (error) => `Error: ${error.message}`, formatError: (error) => `[ERROR] ${error.message}`, formatVersion: (name, version) => `${name} (${version})`, formatErrors: (errors) => errors.map((error) => error.message).join("\\n")}
// Use the custom formatter in a programconst program = Effect.gen(function*() { const formatter = yield* CliOutput.Formatter return formatter.formatVersion("myapp", "1.0.0")}).pipe( Effect.provide(CliOutput.layer(customFormatter)))
await Effect.runPromise(program) // => "myapp (1.0.0)"Services
Service reference for the CLI output formatter. Provides a default implementation that can be overridden for custom formatting or testing.
Signature
declare const Formatter: Reference<Formatter>Example Accessing the output formatter
import { Effect } from "effect"import { CliOutput } from "effect/cli"
// Access the formatter serviceconst program = Effect.gen(function*() { const formatter = yield* CliOutput.Formatter
// Format version information return formatter.formatVersion("my-cli", "2.1.0")})
// Run with default formatterawait Effect.runPromise(program.pipe( Effect.provide(CliOutput.layer(CliOutput.defaultFormatter({ colors: false }))))) // => "my-cli v2.1.0"