Argument
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>>;}import { Argument } from "effect/unstable/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>>;}import { Argument } from "effect/unstable/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>>;}import { Argument } from "effect/unstable/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>;}import { Argument } from "effect/unstable/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>;}import { Option } from "effect"import { Argument } from "effect/unstable/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>;}import { Argument } from "effect/unstable/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>;}import { Effect, FileSystem, Layer, Path, Stdio, Terminal } from "effect"import { Argument, CliError } from "effect/unstable/cli"import { ChildProcessSpawner } from "effect/unstable/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
Transforms 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>;}import { Effect, FileSystem, Layer, Path, Stdio, Terminal } from "effect"import { Argument } from "effect/unstable/cli"import { ChildProcessSpawner } from "effect/unstable/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>>import { Argument } from "effect/unstable/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>;}import { Argument } from "effect/unstable/cli"
const value = Argument.Int("value").pipe( Argument.orElse(() => Argument.String("value")))value.kind // => "argument"orElseResult
Provides 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>>;}import { Argument } from "effect/unstable/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>>;}import { Argument } from "effect/unstable/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
Provides 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>;}import { Argument } from "effect/unstable/cli"
const port = Argument.Int("port").pipe(Argument.withDefault(8080))port.kind // => "argument"withDescription
Adds 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>;}import { Argument } from "effect/unstable/cli"
const filename = Argument.String("filename").pipe( Argument.withDescription("The input file to process"))filename.kind // => "argument"withFallbackConfig
Adds 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>;}import { Config } from "effect"import { Argument } from "effect/unstable/cli"
const repository = Argument.String("repository").pipe( Argument.withFallbackConfig(Config.String("REPOSITORY")))repository.kind // => "argument"withFallbackPrompt
Adds 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>;}import { Argument, Prompt } from "effect/unstable/cli"
const filename = Argument.String("filename").pipe( Argument.withFallbackPrompt(Prompt.String({ message: "Filename" })))filename.kind // => "argument"withSchema
Validates 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>;}import { Schema } from "effect"import { Argument } from "effect/unstable/cli"
const input = Argument.String("input").pipe( Argument.withSchema(Schema.NonEmptyString))input.kind // => "argument"Constructors
ChoiceWithValue
Creates 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]>import { Argument } from "effect/unstable/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>import { Argument } from "effect/unstable/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>import { Argument } from "effect/unstable/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>import { Argument } from "effect/unstable/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>import { Argument } from "effect/unstable/cli"
const config = Argument.FileParse("config", { format: "json" })config.kind // => "argument"FileSchema
Creates 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>import { Schema } from "effect"import { Argument } from "effect/unstable/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>import { Argument } from "effect/unstable/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>import { Argument } from "effect/unstable/cli"
const ratio = Argument.Finite("ratio")ratio.kind // => "argument"Creates a positional integer argument.
Signature
declare function Int(name: string): Argument<number>import { Argument } from "effect/unstable/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]>import { Argument } from "effect/unstable/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>import { Argument } from "effect/unstable/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>import { Argument } from "effect/unstable/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>>import { Argument } from "effect/unstable/cli"
const secret = Argument.Redacted("secret")secret.kind // => "argument"Creates a positional string argument.
Signature
declare function String(name: string): Argument<string>import { Argument } from "effect/unstable/cli"
const filename = Argument.String("filename")filename.kind // => "argument"Metadata
withMetavar
Sets 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>;}import { Argument } from "effect/unstable/cli"
const port = Argument.Int("port").pipe( Argument.withMetavar("PORT"))port.kind // => "argument"