Argument unstable
Defines typed positional arguments for Effect CLI applications.
Arguments consume ordered values after a command name and its flags, then parse them into the types a command handler expects. This module includes constructors for common argument shapes, plus helpers for optional or variadic arguments, schema validation, transformations, defaults, config fallbacks, and prompts for missing values.
Combinators
Creates a variadic argument that requires at least n values.
Signature
declare const atLeast: { <A>(min: number): (self: Argument<A>) => Argument<readonly Array<A>>; <A>(self: Argument<A>, min: number): Argument<readonly Array<A>>;}Example Requiring a minimum number of values
import { Argument } from "effect/cli"
const files = Argument.String("files").pipe(Argument.atLeast(1))files.kind // => "argument"Creates a variadic argument that accepts at most n values.
Signature
declare const atMost: { <A>(max: number): (self: Argument<A>) => Argument<readonly Array<A>>; <A>(self: Argument<A>, max: number): Argument<readonly Array<A>>;}Example Limiting the maximum number of values
import { Argument } from "effect/cli"
const files = Argument.String("files").pipe(Argument.atMost(5))files.kind // => "argument"Creates a variadic argument that accepts between min and max values.
Signature
declare const between: { <A>(min: number, max: number): (self: Argument<A>) => Argument<readonly Array<A>>; <A>(self: Argument<A>, min: number, max: number): Argument<readonly Array<A>>;}Example Requiring a range of values
import { Argument } from "effect/cli"
const files = Argument.String("files").pipe(Argument.between(1, 5))files.kind // => "argument"Filters parsed values, failing with a custom error message if the predicate returns false.
Signature
declare const filter: { <A>(predicate: (a: A) => boolean, onFalse: (a: A) => string): (self: Argument<A>) => Argument<A>; <A>(self: Argument<A>, predicate: (a: A) => boolean, onFalse: (a: A) => string): Argument<A>;}Example Filtering parsed values
import { Argument } from "effect/cli"
const positiveInt = Argument.Int("count").pipe( Argument.filter( (n) => n > 0, (n) => `Expected positive integer, got ${n}` ))positiveInt.kind // => "argument"Filters and transforms parsed values, failing with a custom error message if the filter function returns None.
Signature
declare const filterMap: { <A, B>(f: (a: A) => Option<B>, onNone: (a: A) => string): (self: Argument<A>) => Argument<B>; <A, B>(self: Argument<A>, f: (a: A) => Option<B>, onNone: (a: A) => string): Argument<B>;}Example Filtering and mapping parsed values
import { Option } from "effect"import { Argument } from "effect/cli"
const positiveInt = Argument.Int("count").pipe( Argument.filterMap( (n) => n > 0 ? Option.some(n) : Option.none(), (n) => `Expected positive integer, got ${n}` ))positiveInt.kind // => "argument"Transforms the parsed value of a positional argument.
Signature
declare const map: { <A, B>(f: (a: A) => B): (self: Argument<A>) => Argument<B>; <A, B>(self: Argument<A>, f: (a: A) => B): Argument<B>;}Example Mapping parsed values
import { Argument } from "effect/cli"
const port = Argument.Int("port").pipe( Argument.map((p) => ({ port: p, url: `http://localhost:${p}` })))port.kind // => "argument"Transforms the parsed value of a positional argument using an effectful function.
Signature
declare const mapEffect: { <A, B>(f: (a: A) => Effect<B, CliError, Environment>): (self: Argument<A>) => Argument<B>; <A, B>(self: Argument<A>, f: (a: A) => Effect<B, CliError, Environment>): Argument<B>;}Example Validating values effectfully
import { Effect, FileSystem, Layer, Path, Stdio, Terminal } from "effect"import { Argument, CliError } from "effect/cli"import { ChildProcessSpawner } from "effect/process"
const CliTestLayer = Layer.mergeAll( FileSystem.layerNoop({}), Path.layer, Stdio.layerTest({}), Layer.succeed(Terminal.Terminal, Terminal.make({ columns: Effect.succeed(80), rows: Effect.succeed(24), readInput: Effect.die("unused"), readLine: Effect.die("unused"), display: () => Effect.void })), Layer.succeed( ChildProcessSpawner.ChildProcessSpawner, ChildProcessSpawner.make(() => Effect.die("unused")) ))
const files = Argument.String("files").pipe( Argument.mapEffect((file) => file.endsWith(".txt") ? Effect.succeed(file) : Effect.fail( new CliError.UserError({ cause: new Error(`Unsupported file extension: ${file}`), userMessage: "Only .txt files allowed" }) ) ))
const [, value] = await Effect.runPromise( files.parse({ arguments: ["notes.txt"], flags: {} }).pipe(Effect.provide(CliTestLayer)))value // => "notes.txt"mapTryCatch
unstableTransforms the parsed value of a positional argument using a function that may throw.
Signature
declare const mapTryCatch: { <A, B>(f: (a: A) => B, onError: (error: unknown) => string): (self: Argument<A>) => Argument<B>; <A, B>(self: Argument<A>, f: (a: A) => B, onError: (error: unknown) => string): Argument<B>;}Example Mapping values that may throw
import { Effect, FileSystem, Layer, Path, Stdio, Terminal } from "effect"import { Argument } from "effect/cli"import { ChildProcessSpawner } from "effect/process"
const CliTestLayer = Layer.mergeAll( FileSystem.layerNoop({}), Path.layer, Stdio.layerTest({}), Layer.succeed(Terminal.Terminal, Terminal.make({ columns: Effect.succeed(80), rows: Effect.succeed(24), readInput: Effect.die("unused"), readLine: Effect.die("unused"), display: () => Effect.void })), Layer.succeed( ChildProcessSpawner.ChildProcessSpawner, ChildProcessSpawner.make(() => Effect.die("unused")) ))
const json = Argument.String("data").pipe( Argument.mapTryCatch( (str) => JSON.parse(str), (error) => `Invalid JSON: ${error instanceof Error ? error.message : String(error)}` ))
const [, value] = await Effect.runPromise( json.parse({ arguments: ['{"enabled":true}'], flags: {} }).pipe(Effect.provide(CliTestLayer)))value // => { enabled: true }Makes a positional argument optional.
Signature
declare function optional<A>(arg: Argument<A>): Argument<Option<A>>Example Making an argument optional
import { Argument } from "effect/cli"
const optionalVersion = Argument.String("version").pipe(Argument.optional)optionalVersion.kind // => "argument"Provides a fallback argument to use if this argument fails to parse.
Signature
declare const orElse: { <B>(that: LazyArg<Argument<B>>): <A>(self: Argument<A>) => Argument<B | A>; <A, B>(self: Argument<A>, that: LazyArg<Argument<B>>): Argument<A | B>;}Example Providing a fallback argument
import { Argument } from "effect/cli"
const value = Argument.Int("value").pipe( Argument.orElse(() => Argument.String("value")))value.kind // => "argument"orElseResult
unstableProvides a fallback argument, wrapping results in Result to distinguish which succeeded.
Signature
declare const orElseResult: { <B>(that: LazyArg<Argument<B>>): <A>(self: Argument<A>) => Argument<Result<A, B>>; <A, B>(self: Argument<A>, that: LazyArg<Argument<B>>): Argument<Result<A, B>>;}Example Returning which fallback succeeded
import { Argument } from "effect/cli"
const source = Argument.File("source").pipe( Argument.orElseResult(() => Argument.String("url")))// Returns Result<string, string>source.kind // => "argument"Creates a variadic positional argument that accepts multiple values.
Signature
declare const variadic: { (options?: VariadicParamOptions): <A>(self: Argument<A>) => Argument<readonly Array<A>>; <A>(self: Argument<A>, options?: VariadicParamOptions): Argument<readonly Array<A>>;}Example Accepting multiple values
import { Argument } from "effect/cli"
// Accept any number of filesconst anyFiles = Argument.String("files").pipe(Argument.variadic)
// Accept at least 1 fileconst atLeastOneFile = Argument.String("files").pipe( Argument.variadic({ min: 1 }))
// Accept between 1 and 5 filesconst limitedFiles = Argument.String("files").pipe( Argument.variadic({ min: 1, max: 5 }))
const kinds = [anyFiles.kind, atLeastOneFile.kind, limitedFiles.kind] // => ["argument", "argument", "argument"]withDefault
unstableProvides a default value for a positional argument.
Signature
declare const withDefault: { <B>(defaultValue: B | Effect<B, CliError, Environment>): <A>(self: Argument<A>) => Argument<B | A>; <A, B>(self: Argument<A>, defaultValue: B | Effect<B, CliError, Environment>): Argument<A | B>;}Example Providing a default value
import { Argument } from "effect/cli"
const port = Argument.Int("port").pipe(Argument.withDefault(8080))port.kind // => "argument"withDescription
unstableAdds a description to a positional argument.
Signature
declare const withDescription: { <A>(description: string): (self: Argument<A>) => Argument<A>; <A>(self: Argument<A>, description: string): Argument<A>;}Example Adding an argument description
import { Argument } from "effect/cli"
const filename = Argument.String("filename").pipe( Argument.withDescription("The input file to process"))filename.kind // => "argument"withFallbackConfig
unstableAdds a fallback config that is loaded when a required argument is missing.
Signature
declare const withFallbackConfig: { <B>(config: Config<B>): <A>(self: Argument<A>) => Argument<B | A>; <A, B>(self: Argument<A>, config: Config<B>): Argument<A | B>;}Example Loading a fallback config
import { Config } from "effect"import { Argument } from "effect/cli"
const repository = Argument.String("repository").pipe( Argument.withFallbackConfig(Config.String("REPOSITORY")))repository.kind // => "argument"withFallbackPrompt
unstableAdds a fallback prompt that is shown when a required argument is missing.
Signature
declare const withFallbackPrompt: { <B>(prompt: FallbackPrompt<B>): <A>(self: Argument<A>) => Argument<B | A>; <A, B>(self: Argument<A>, prompt: FallbackPrompt<B>): Argument<A | B>;}Example Showing a fallback prompt
import { Argument, Prompt } from "effect/cli"
const filename = Argument.String("filename").pipe( Argument.withFallbackPrompt(Prompt.String({ message: "Filename" })))filename.kind // => "argument"withSchema
unstableValidates parsed values against a Schema.
Signature
declare const withSchema: { <A, B>(schema: ConstraintCodec<B, A, Environment, unknown>): (self: Argument<A>) => Argument<B>; <A, B>(self: Argument<A>, schema: ConstraintCodec<B, A, Environment, unknown>): Argument<B>;}Example Validating parsed values with a schema
import { Schema } from "effect"import { Argument } from "effect/cli"
const input = Argument.String("input").pipe( Argument.withSchema(Schema.NonEmptyString))input.kind // => "argument"Constructors
ChoiceWithValue
unstableCreates a positional choice argument with custom value mapping.
Signature
declare function ChoiceWithValue<Choices extends readonly Array<readonly [string, any]>>(name: string, choices: Choices): Argument<Choices[number][1]>Example Mapping choices to values
import { Argument } from "effect/cli"
const logLevel = Argument.ChoiceWithValue("level", [ ["debug", 0], ["info", 1], ["warn", 2], ["error", 3]])logLevel.kind // => "argument"Creates a positional date argument.
Signature
declare function Date(name: string): Argument<Date>Example Creating a date argument
import { Argument } from "effect/cli"
const startDate = Argument.Date("start-date")startDate.kind // => "argument"Creates a positional directory path argument.
Signature
declare function Directory(name: string, options?: { readonly mustExist?: boolean;}): Argument<string>Example Creating a directory path argument
import { Argument } from "effect/cli"
const workspace = Argument.Directory("workspace", { mustExist: true }) // Must existworkspace.kind // => "argument"Creates a positional file path argument.
Signature
declare function File(name: string, options?: { readonly mustExist?: boolean;}): Argument<string>Example Creating file path arguments
import { Argument } from "effect/cli"
const inputFile = Argument.File("input", { mustExist: true }) // Must existconst outputFile = Argument.File("output", { mustExist: false }) // Must not existconst kinds = [inputFile.kind, outputFile.kind] // => ["argument", "argument"]Creates a positional argument that reads a file and parses its content.
Details
The parser is chosen from the explicit format option or, when omitted, the
file extension. The parsed value is unknown; use fileSchema when the
parsed content should also be decoded with a Schema.
Signature
declare function FileParse(name: string, options?: FileParseOptions): Argument<unknown>Example Parsing file content
import { Argument } from "effect/cli"
const config = Argument.FileParse("config", { format: "json" })config.kind // => "argument"FileSchema
unstableCreates a positional argument that reads and validates file content using a schema.
Signature
declare function FileSchema<A>(name: string, schema: ConstraintDecoder<A, Environment>, options?: { readonly errorFormatter?: Formatter<string>; readonly format?: "json" | "ini" | "toml" | "yaml";}): Argument<A>Example Validating file content with a schema
import { Schema } from "effect"import { Argument } from "effect/cli"
const ConfigSchema = Schema.Struct({ port: Schema.Number, host: Schema.String})
const config = Argument.FileSchema("config", ConfigSchema)config.kind // => "argument"Creates a positional argument that reads file content as a string.
Signature
declare function FileText(name: string): Argument<string>Example Reading file text
import { Argument } from "effect/cli"
const config = Argument.FileText("config-file")config.kind // => "argument"Creates a positional argument that parses finite numbers.
Signature
declare function Finite(name: string): Argument<number>Example Parsing a finite number
import { Argument } from "effect/cli"
const ratio = Argument.Finite("ratio")ratio.kind // => "argument"Creates a positional integer argument.
Signature
declare function Int(name: string): Argument<number>Example Creating an integer argument
import { Argument } from "effect/cli"
const count = Argument.Int("count")count.kind // => "argument"Creates a positional choice argument.
Signature
declare function Literals<Choices extends readonly Array<string>>(name: string, choices: Choices): Argument<Choices[number]>Example Creating a choice argument
import { Argument } from "effect/cli"
const environment = Argument.Literals("environment", ["dev", "staging", "prod"])environment.kind // => "argument"An argument that always fails to parse.
Signature
declare const Never: Argument<never>Example Creating a sentinel argument
import { Argument } from "effect/cli"
const noArg = Argument.NevernoArg.kind // => "argument"Creates a positional path argument.
Signature
declare function Path(name: string, options?: { mustExist?: boolean; pathType?: "either" | "file" | "directory";}): Argument<string>Example Creating a path argument
import { Argument } from "effect/cli"
const configPath = Argument.Path("config")configPath.kind // => "argument"Creates a positional redacted argument that obscures its value.
Signature
declare function Redacted(name: string): Argument<Redacted<string>>Example Creating a redacted argument
import { Argument } from "effect/cli"
const secret = Argument.Redacted("secret")secret.kind // => "argument"Creates a positional string argument.
Signature
declare function String(name: string): Argument<string>Example Creating a string argument
import { Argument } from "effect/cli"
const filename = Argument.String("filename")filename.kind // => "argument"Metadata
withMetavar
unstableSets a custom metavar (placeholder name) for the argument in help documentation.
Details
The metavar is displayed in usage text to indicate what value the user should provide.
For example, <FILE> shows FILE as the metavar.
Signature
declare const withMetavar: { <A>(metavar: string): (self: Argument<A>) => Argument<A>; <A>(self: Argument<A>, metavar: string): Argument<A>;}Example Setting a metavar
import { Argument } from "effect/cli"
const port = Argument.Int("port").pipe( Argument.withMetavar("PORT"))port.kind // => "argument"