Skip to content
Effect Days 2026 Get your ticket

Flag

Defines named options for command-line applications.

A Flag<A> describes how to read one named value from parsed command-line input, validate it, and produce an A. Flags are useful for inputs such as ports, verbosity switches, configuration files, output directories, choices, secrets, and repeated values. The helpers here build flags with aliases, defaults, optional values, prompts, configuration fallbacks, validation, and value transformations.

36 exports Added in v4.0.0 Source

Aliasing

withAlias

Added in v4.0.0 Source

Adds an alias to a flag, allowing it to be referenced by multiple names.

Signature

declare const withAlias: {
<A>(alias: string): (self: Flag<A>) => Flag<A>;
<A>(self: Flag<A>, alias: string): Flag<A>;
}

Example

(Adding flag aliases)

import { Flag } from "effect/unstable/cli"
// Flag can be used as both --verbose and -v
const verboseFlag = Flag.boolean("verbose").pipe(
Flag.withAlias("v")
)
// Multiple aliases can be chained
const helpFlag = Flag.boolean("help").pipe(
Flag.withAlias("h"),
Flag.withAlias("?")
)
const kinds = [verboseFlag.kind, helpFlag.kind] // => ["flag", "flag"]

Alternatives

orElse

Added in v4.0.0 Source

Provides an alternative flag if the first one fails to parse.

Signature

declare const orElse: {
<B>(that: LazyArg<Flag<B>>): <A>(self: Flag<A>) => Flag<B | A>;
<A, B>(self: Flag<A>, that: LazyArg<Flag<B>>): Flag<A | B>;
}

Example

(Falling back to another flag)

import { Flag } from "effect/unstable/cli"
// Try parsing as integer, fallback to string
const valueFlag = Flag.orElse(
Flag.integer("value"),
() => Flag.string("value")
)
// Multiple input sources with fallback
const configFlag = Flag.orElse(
Flag.file("config"),
() => Flag.string("config-url")
)
const kinds = [valueFlag.kind, configFlag.kind] // => ["flag", "flag"]

orElseResult

Added in v4.0.0 Source

Tries to parse with the first flag, then the second, returning a Result that indicates which succeeded.

Signature

declare const orElseResult: {
<B>(that: LazyArg<Flag<B>>): <A>(self: Flag<A>) => Flag<Result<A, B>>;
<A, B>(self: Flag<A>, that: LazyArg<Flag<B>>): Flag<Result<A, B>>;
}

Example

(Returning fallback results)

import { Effect, FileSystem, Layer, Path, Result, Stdio, Terminal } from "effect"
import { Flag } 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 sourceFlag = Flag.orElseResult(
Flag.string("source"),
() => Flag.string("source-url")
)
const program = Effect.gen(function*() {
const [, source] = yield* sourceFlag.parse({
arguments: [],
flags: { "source-url": ["https://example.com"] }
})
return source
})
await Effect.runPromise(program.pipe(Effect.provide(CliTestLayer))) // => Result.fail("https://example.com")

Combinators

Adds a fallback config that is loaded when a required flag is missing.

Signature

declare const withFallbackConfig: {
<B>(config: Config<B>): <A>(self: Flag<A>) => Flag<B | A>;
<A, B>(self: Flag<A>, config: Config<B>): Flag<A | B>;
}

Example

(Falling back to config)

import { Config } from "effect"
import { Flag } from "effect/unstable/cli"
const verbose = Flag.boolean("verbose").pipe(
Flag.withFallbackConfig(Config.boolean("VERBOSE"))
)
verbose.kind // => "flag"

Adds a fallback prompt that is shown when a required flag is missing.

Signature

declare const withFallbackPrompt: {
<B>(prompt: FallbackPrompt<B>): <A>(self: Flag<A>) => Flag<B | A>;
<A, B>(self: Flag<A>, prompt: FallbackPrompt<B>): Flag<A | B>;
}

Example

(Falling back to prompts)

import { Flag, Prompt } from "effect/unstable/cli"
const name = Flag.string("name").pipe(
Flag.withFallbackPrompt(Prompt.text({ message: "Name" }))
)
name.kind // => "flag"

Constructors

boolean

Added in v4.0.0 Source

Creates a boolean flag that can be enabled or disabled.

Signature

declare function boolean(name: string): Flag<boolean>

Example

(Creating boolean flags)

import { Flag } from "effect/unstable/cli"
const verboseFlag = Flag.boolean("verbose")
// Usage: --verbose (true) or --no-verbose (false)
// Omission fails unless the flag is made optional or given a fallback.
verboseFlag.kind // => "flag"

choice

Added in v4.0.0 Source

Creates a flag that accepts one of the provided string choices and returns the selected string.

When to use

Use when you need to define a named CLI flag with fixed string choices and no custom value mapping.

Gotchas

An empty choices array compiles, but no input value can parse successfully.

See

Signature

declare function choice<Choices extends readonly Array<string>>(name: string, choices: Choices): Flag<Choices[number]>

Constructs option parameters that represent a choice between several inputs. Each tuple maps a string flag value to an associated typed value.

Signature

declare function choiceWithValue<Choice extends readonly Array<readonly [string, any]>>(name: string, choices: Choice): Flag<Choice[number][1]>

Example

(Creating flag choices with values)

import { Flag } from "effect/unstable/cli"
// simple enum like choice mapping directly to string union
const color = Flag.choice("color", ["red", "green", "blue"])
// choice with custom value mapping
const logLevel = Flag.choiceWithValue("log-level", [
["debug", "Debug" as const],
["info", "Info" as const],
["error", "Error" as const]
])
const kinds = [color.kind, logLevel.kind] // => ["flag", "flag"]

date

Added in v4.0.0 Source

Creates a date flag that accepts date input in ISO format.

Signature

declare function date(name: string): Flag<Date>

Example

(Creating date flags)

import { Flag } from "effect/unstable/cli"
const startDateFlag = Flag.date("start-date")
// Usage: --start-date 2023-12-25
startDateFlag.kind // => "flag"

directory

Added in v4.0.0 Source

Creates a directory path flag that accepts directory paths with optional existence validation.

Signature

declare function directory(name: string, options?: {
readonly mustExist?: boolean;
}): Flag<string>

Example

(Creating directory flags)

import { Flag } from "effect/unstable/cli"
// Basic directory flag
const outputFlag = Flag.directory("output")
// Usage: --output ./build
// Directory that must exist
const sourceFlag = Flag.directory("source", { mustExist: true })
// Usage: --source ./src (directory must exist)
const kinds = [outputFlag.kind, sourceFlag.kind] // => ["flag", "flag"]

file

Added in v4.0.0 Source

Creates a file path flag that accepts file paths with optional existence validation.

Signature

declare function file(name: string, options?: {
readonly mustExist?: boolean;
}): Flag<string>

Example

(Creating file flags)

import { Flag } from "effect/unstable/cli"
// Basic file flag
const inputFlag = Flag.file("input")
// Usage: --input ./data.json
// File that must exist
const configFlag = Flag.file("config", { mustExist: true })
// Usage: --config ./config.yaml (file must exist)
const kinds = [inputFlag.kind, configFlag.kind] // => ["flag", "flag"]

fileParse

Added in v4.0.0 Source

Creates a flag that reads and parses the content of the specified file.

Details

The parser that is utilized will depend on the specified format, or the extension of the file passed on the command-line if no format is specified.

Signature

declare function fileParse(name: string, options?: FileParseOptions): Flag<unknown>

Example

(Parsing file contents)

import { Flag } from "effect/unstable/cli"
// Will use the extension of the file passed on the command line to determine
// the parser to use
const config = Flag.fileParse("config")
// Will use the JSON parser
const jsonConfig = Flag.fileParse("json-config", { format: "json" })
const kinds = [config.kind, jsonConfig.kind] // => ["flag", "flag"]

fileSchema

Added in v4.0.0 Source

Creates a flag that reads and validates file content using the specified schema.

Signature

declare function fileSchema<A>(name: string, schema: ConstraintDecoder<A, Environment>, options?: {
readonly errorFormatter?: Formatter<string>;
readonly format?: "json" | "ini" | "toml" | "yaml";
}): Flag<A>

Example

(Validating file contents)

import { Schema } from "effect"
import { Flag } from "effect/unstable/cli"
const ConfigSchema = Schema.Struct({
port: Schema.Number,
host: Schema.String
})
const config = Flag.fileSchema("config", ConfigSchema, { format: "json" })
config.kind // => "flag"

fileText

Added in v4.0.0 Source

Creates a flag that reads and returns file content as a string.

Signature

declare function fileText(name: string): Flag<string>

Example

(Reading file text)

import { Flag } from "effect/unstable/cli"
const config = Flag.fileText("config-file")
// --config-file ./app.json will read the file content
config.kind // => "flag"

float

Added in v4.0.0 Source

Creates a float flag that accepts decimal number input.

Signature

declare function float(name: string): Flag<number>

Example

(Creating float flags)

import { Flag } from "effect/unstable/cli"
const rateFlag = Flag.float("rate")
// Usage: --rate 3.14
rateFlag.kind // => "flag"

integer

Added in v4.0.0 Source

Creates an integer flag that accepts whole number input.

Signature

declare function integer(name: string): Flag<number>

Example

(Creating integer flags)

import { Flag } from "effect/unstable/cli"
const portFlag = Flag.integer("port")
// Usage: --port 8080
portFlag.kind // => "flag"

keyValuePair

Added in v4.0.0 Source

Creates a flag that parses key=value pairs.

When to use

Use when you need a CLI flag that accepts one or more key=value configuration entries.

Details

Requires at least one key=value pair. Multiple pairs are merged into a single record.

Signature

declare function keyValuePair(name: string): Flag<Record<string, string>>

Example

(Parsing key-value pairs)

import { Flag } from "effect/unstable/cli"
const env = Flag.keyValuePair("env")
// --env FOO=bar --env BAZ=qux will parse to { FOO: "bar", BAZ: "qux" }
env.kind // => "flag"

none

Added in v4.0.0 Source

Creates an empty sentinel flag that always fails to parse. This is useful for creating placeholder flags or for combinators.

Signature

declare const none: Flag<never>

Example

(Creating sentinel flags)

import { Flag } from "effect/unstable/cli"
const makeValueFlag = (includeValue: boolean) =>
includeValue ? Flag.string("value") : Flag.none
makeValueFlag(true) === Flag.none // => false
makeValueFlag(false) === Flag.none // => true

path

Added in v4.0.0 Source

Creates a path flag that accepts file system path input with validation options.

Signature

declare function path(name: string, options?: {
readonly mustExist?: boolean;
readonly pathType?: "either" | "file" | "directory";
readonly typeName?: string;
}): Flag<string>

Example

(Creating path flags)

import { Flag } from "effect/unstable/cli"
// Basic path flag
const pathFlag = Flag.path("config-path")
// File-only path that must exist
const fileFlag = Flag.path("input-file", {
pathType: "file",
mustExist: true
})
// Directory path with custom type name
const dirFlag = Flag.path("output-dir", {
pathType: "directory",
typeName: "OUTPUT_DIRECTORY"
})
const kinds = [pathFlag.kind, fileFlag.kind, dirFlag.kind] // => ["flag", "flag", "flag"]

redacted

Added in v4.0.0 Source

Creates a string flag whose parsed value is wrapped in Redacted.Redacted so stringification and logging redact the value.

Gotchas

Values supplied on the command line may still be visible to the operating system or shell history.

Signature

declare function redacted(name: string): Flag<Redacted<string>>

Example

(Creating redacted flags)

import { Effect, FileSystem, Layer, Path, Redacted, Stdio, Terminal } from "effect"
import { Flag } 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 passwordFlag = Flag.redacted("password")
const program = Effect.gen(function*() {
const [, password] = yield* passwordFlag.parse({
arguments: [],
flags: { "password": ["abc123"] }
})
return Redacted.value(password).length
})
await Effect.runPromise(program.pipe(Effect.provide(CliTestLayer))) // => 6

string

Added in v4.0.0 Source

Creates a string flag that accepts text input.

Signature

declare function string(name: string): Flag<string>

Example

(Creating string flags)

import { Flag } from "effect/unstable/cli"
const nameFlag = Flag.string("name")
// Usage: --name "John Doe"
nameFlag.kind // => "flag"

Filtering

filter

Added in v4.0.0 Source

Filters a flag value based on a predicate, failing with a custom error if the predicate returns false.

Signature

declare const filter: {
<A>(predicate: (a: A) => boolean, onFalse: (a: A) => string): (self: Flag<A>) => Flag<A>;
<A>(self: Flag<A>, predicate: (a: A) => boolean, onFalse: (a: A) => string): Flag<A>;
}

Example

(Filtering parsed values)

import { Flag } from "effect/unstable/cli"
// Ensure port is in valid range
const portFlag = Flag.integer("port").pipe(
Flag.filter(
(port) => port >= 1 && port <= 65535,
(port) => `Port ${port} is out of range (1-65535)`
)
)
// Ensure non-empty string
const nameFlag = Flag.string("name").pipe(
Flag.filter(
(name) => name.trim().length > 0,
() => "Name cannot be empty"
)
)
const kinds = [portFlag.kind, nameFlag.kind] // => ["flag", "flag"]

filterMap

Added in v4.0.0 Source

Transforms and filters a flag value, failing with a custom error if the transformation returns None.

Signature

declare const filterMap: {
<A, B>(f: (a: A) => Option<B>, onNone: (a: A) => string): (self: Flag<A>) => Flag<B>;
<A, B>(self: Flag<A>, f: (a: A) => Option<B>, onNone: (a: A) => string): Flag<B>;
}

Example

(Filtering and transforming values)

import { Option } from "effect"
import { Flag } from "effect/unstable/cli"
// Parse positive integers only
const positiveInt = Flag.integer("count").pipe(
Flag.filterMap(
(n) => n > 0 ? Option.some(n) : Option.none(),
(n) => `Expected positive integer, got ${n}`
)
)
// Parse valid email addresses
const emailFlag = Flag.string("email").pipe(
Flag.filterMap(
(email) => email.includes("@") ? Option.some(email) : Option.none(),
(email) => `Invalid email address: ${email}`
)
)
const kinds = [positiveInt.kind, emailFlag.kind] // => ["flag", "flag"]

Mapping

map

Added in v4.0.0 Source

Transforms the parsed value of a flag using a mapping function.

Signature

declare const map: {
<A, B>(f: (a: A) => B): (self: Flag<A>) => Flag<B>;
<A, B>(self: Flag<A>, f: (a: A) => B): Flag<B>;
}

Example

(Mapping parsed values)

import { Flag } from "effect/unstable/cli"
// Convert string to uppercase
const nameFlag = Flag.string("name").pipe(
Flag.map((name) => name.toUpperCase())
)
// Convert port to URL
const urlFlag = Flag.integer("port").pipe(
Flag.map((port) => `http://localhost:${port}`)
)
const kinds = [nameFlag.kind, urlFlag.kind] // => ["flag", "flag"]

mapEffect

Added in v4.0.0 Source

Transforms the parsed value using an Effect that can perform IO operations.

Signature

declare const mapEffect: {
<A, B>(f: (a: A) => Effect<B, CliError, Environment>): (self: Flag<A>) => Flag<B>;
<A, B>(self: Flag<A>, f: (a: A) => Effect<B, CliError, Environment>): Flag<B>;
}

Example

(Mapping parsed values effectfully)

import { Effect, FileSystem, Layer, Path, Stdio, Terminal } from "effect"
import { Flag } 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 upperName = Flag.string("name").pipe(
Flag.mapEffect((name) => Effect.succeed(name.toUpperCase()))
)
const [, value] = await Effect.runPromise(
upperName.parse({
arguments: [],
flags: { name: ["alice"] }
}).pipe(Effect.provide(CliTestLayer))
)
value // => "ALICE"

mapTryCatch

Added in v4.0.0 Source

Transforms the parsed value using a function that might throw, with error handling.

Signature

declare const mapTryCatch: {
<A, B>(f: (a: A) => B, onError: (error: unknown) => string): (self: Flag<A>) => Flag<B>;
<A, B>(self: Flag<A>, f: (a: A) => B, onError: (error: unknown) => string): Flag<B>;
}

Example

(Mapping thrown errors)

import { Effect, FileSystem, Layer, Path, Stdio, Terminal } from "effect"
import { Flag } 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"))
)
)
// Parse JSON string with error handling
const jsonFlag = Flag.string("config").pipe(
Flag.mapTryCatch(
(json) => JSON.parse(json),
(error) => `Invalid JSON: ${error}`
)
)
// Parse URL with error handling
const urlFlag = Flag.string("url").pipe(
Flag.mapTryCatch(
(url) => new URL(url),
(error) => `Invalid URL: ${error}`
)
)
const [, value] = await Effect.runPromise(
jsonFlag.parse({
arguments: [],
flags: { config: ['{"enabled":true}'] }
}).pipe(Effect.provide(CliTestLayer))
)
value // => { enabled: true }

Metadata

Adds a description to a flag for help documentation.

Signature

declare const withDescription: {
<A>(description: string): (self: Flag<A>) => Flag<A>;
<A>(self: Flag<A>, description: string): Flag<A>;
}

Example

(Adding help descriptions)

import { Flag } from "effect/unstable/cli"
const portFlag = Flag.integer("port").pipe(
Flag.withDescription("The port number to listen on")
)
const configFlag = Flag.file("config").pipe(
Flag.withDescription("Path to the configuration file")
)
const kinds = [portFlag.kind, configFlag.kind] // => ["flag", "flag"]

withHidden

Added in v4.0.0 Source

Hides a flag from generated help output and shell completions while keeping it fully parseable on the command line.

When to use

Use when experimental or internal flags should be accepted but not advertised, such as --experimental-foo, debug toggles, or escape hatches that are not yet committed to the public CLI surface.

Signature

declare function withHidden<A>(self: Flag<A>): Flag<A>

Example

(Hiding a flag from help)

import { Flag } from "effect/unstable/cli"
// Flag still parses --experimental-foo, but it does not appear in --help.
const experimental = Flag.boolean("experimental-foo").pipe(
Flag.withHidden
)
experimental.kind // => "flag"

withMetavar

Added in v4.0.0 Source

Sets a custom metavar (placeholder name) for the flag in help documentation.

Details

The metavar is displayed in usage text to indicate what value the user should provide. For example, --output FILE shows FILE as the metavar.

Signature

declare const withMetavar: {
<A>(metavar: string): (self: Flag<A>) => Flag<A>;
<A>(self: Flag<A>, metavar: string): Flag<A>;
}

Example

(Setting metavars)

import { Flag } from "effect/unstable/cli"
const databaseFlag = Flag.string("database-url").pipe(
Flag.withMetavar("URL"),
Flag.withDescription("Database connection URL")
)
// In help: --database-url URL
const timeoutFlag = Flag.integer("timeout").pipe(
Flag.withMetavar("SECONDS")
)
// In help: --timeout SECONDS
const kinds = [databaseFlag.kind, timeoutFlag.kind] // => ["flag", "flag"]

Models

Flag interface

Added in v4.0.0 Source

Represents a command-line flag.

Signature

interface Flag<A> extends Param<typeof Param.flagKind, A> {}

Optionality

optional

Added in v4.0.0 Source

Makes a flag optional, returning an Option type that can be None if not provided.

Signature

declare function optional<A>(param: Flag<A>): Flag<Option<A>>

Example

(Making flags optional)

import { Effect, FileSystem, Layer, Option, Path, Stdio, Terminal } from "effect"
import { Flag } 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 optionalPort = Flag.optional(Flag.integer("port"))
const program = Effect.gen(function*() {
const [, port] = yield* optionalPort.parse({
arguments: [],
flags: { "port": ["4000"] }
})
return port
})
await Effect.runPromise(program.pipe(Effect.provide(CliTestLayer))) // => Option.some(4000)

withDefault

Added in v4.0.0 Source

Provides a default value for a flag when it's not specified.

Signature

declare const withDefault: {
<B>(defaultValue: B | Effect<B, CliError, Environment>): <A>(self: Flag<A>) => Flag<B | A>;
<A, B>(self: Flag<A>, defaultValue: B | Effect<B, CliError, Environment>): Flag<A | B>;
}

Example

(Providing default values)

import { Flag } from "effect/unstable/cli"
const portFlag = Flag.integer("port").pipe(
Flag.withDefault(8080)
)
// If --port is not provided, defaults to 8080
const hostFlag = Flag.string("host").pipe(
Flag.withDefault("localhost")
)
// If --host is not provided, defaults to "localhost"
const kinds = [portFlag.kind, hostFlag.kind] // => ["flag", "flag"]

Repetition

atLeast

Added in v4.0.0 Source

Ensures a flag is specified at least a minimum number of times.

Signature

declare const atLeast: {
<A>(min: number): (self: Flag<A>) => Flag<readonly Array<A>>;
<A>(self: Flag<A>, min: number): Flag<readonly Array<A>>;
}

Example

(Requiring repeated values)

import { Flag } from "effect/unstable/cli"
const sourceFlag = Flag.atLeast(Flag.file("source"), 2)
// Requires at least 2 source files
// Usage: --source file1.ts --source file2.ts
const tagFlag = Flag.string("tag").pipe(
Flag.atLeast(1)
)
// Requires at least 1 tag
const kinds = [sourceFlag.kind, tagFlag.kind] // => ["flag", "flag"]

atMost

Added in v4.0.0 Source

Ensures a flag is specified at most a maximum number of times.

Signature

declare const atMost: {
<A>(max: number): (self: Flag<A>) => Flag<readonly Array<A>>;
<A>(self: Flag<A>, max: number): Flag<readonly Array<A>>;
}

Example

(Limiting repeated values)

import { Flag } from "effect/unstable/cli"
const warningFlag = Flag.atMost(Flag.string("warning"), 3)
// Allows up to 3 warning flags
// Usage: --warning w1 --warning w2 --warning w3
const debugFlag = Flag.string("debug").pipe(
Flag.atMost(1)
)
// Allows at most 1 debug flag
const kinds = [warningFlag.kind, debugFlag.kind] // => ["flag", "flag"]

between

Added in v4.0.0 Source

Ensures a flag is specified between a minimum and maximum number of times.

Signature

declare const between: {
<A>(min: number, max: number): (self: Flag<A>) => Flag<readonly Array<A>>;
<A>(self: Flag<A>, min: number, max: number): Flag<readonly Array<A>>;
}

Example

(Bounding repeated values)

import { Flag } from "effect/unstable/cli"
const hostFlag = Flag.between(Flag.string("host"), 1, 3)
// Requires 1-3 host flags
// Usage: --host host1 --host host2
const excludeFlag = Flag.string("exclude").pipe(
Flag.between(0, 5)
)
// Allows 0-5 exclude patterns
const kinds = [hostFlag.kind, excludeFlag.kind] // => ["flag", "flag"]

Schemas

withSchema

Added in v4.0.0 Source

Validates and transforms a flag value using a Schema codec.

Signature

declare const withSchema: {
<A, B>(schema: ConstraintCodec<B, A, Environment, unknown>): (self: Flag<A>) => Flag<B>;
<A, B>(self: Flag<A>, schema: ConstraintCodec<B, A, Environment, unknown>): Flag<B>;
}

Example

(Validating with schemas)

import { Schema } from "effect"
import { Flag } from "effect/unstable/cli"
const isEmail = Schema.isPattern(/^[^\s@]+@[^\s@]+\.[^\s@]+$/, {
message: "Must be a valid email address"
})
// Parse and validate email with custom schema
const EmailSchema = Schema.String.pipe(
Schema.check(isEmail)
)
const emailFlag = Flag.string("email").pipe(
Flag.withSchema(EmailSchema)
)
// Parse JSON configuration with schema validation
const ConfigSchema = Schema.Struct({
port: Schema.Number,
host: Schema.String,
ssl: Schema.optional(Schema.Boolean)
}).pipe(Schema.fromJsonString)
const configFlag = Flag.string("config").pipe(
Flag.withSchema(ConfigSchema)
)
const kinds = [emailFlag.kind, configFlag.kind] // => ["flag", "flag"]