Skip to content

Command

Main building block for defining and running Effect-based command-line applications.

A Command combines a name, typed flags and positional arguments, optional subcommands, help metadata, and an effectful handler. The module includes builders for command trees and the runners that parse command-line input, handle built-in help and version behavior, render help through CliOutput, and execute the selected handler.

27 exports Added in v4.0.0 Source

Combinators

annotate

Added in v4.0.0 Source

Adds a custom annotation to a command.

When to use

Use to attach one command-scoped metadata value under a Context.Key, especially for consumers such as custom help formatters.

Details

Annotations are stored on the command's annotation context and flow into generated help document annotations.

Gotchas

Adding the same Context.Key again replaces the earlier value.

See

Signature

declare const annotate: {
  <I, S>(
    service: Key<I, S>,
    value: NoInfer<S>,
  ): <Name extends string, Input, E, R, ContextInput>(
    self: Command<Name, Input, ContextInput, E, R>,
  ) => Command<Name, Input, ContextInput, E, R>;
  <Name extends string, Input, E, R, ContextInput, I, S>(
    self: Command<Name, Input, ContextInput, E, R>,
    service: Key<I, S>,
    value: NoInfer<S>,
  ): Command<Name, Input, ContextInput, E, R>;
};

Merges a Context of annotations into a command.

When to use

Use when you need to attach an already-built Context.Context of command annotations.

Details

Merged annotations are stored on the command and exposed through generated help document annotations.

Gotchas

If both contexts contain the same Context.Key, the incoming annotations context wins.

See

  • annotate for adding a single annotation without constructing a Context

Signature

declare const annotateMerge: {
  <I>(
    annotations: Context<I>,
  ): <Name extends string, Input, E, R, ContextInput>(
    self: Command<Name, Input, ContextInput, E, R>,
  ) => Command<Name, Input, ContextInput, E, R>;
  <Name extends string, Input, E, R, ContextInput, I>(
    self: Command<Name, Input, ContextInput, E, R>,
    annotations: Context<I>,
  ): Command<Name, Input, ContextInput, E, R>;
};

unlisted

Added in v4.0.0 Source

Omits a subcommand from parent help output, shell completions, and "did you mean?" suggestions while keeping it fully invocable by exact name.

When to use

Use when experimental or internal subcommands should be accepted but not advertised on the public CLI surface.

Signature

declare function unlisted<Name extends string, Input, E, R, ContextInput>(
  self: Command<Name, Input, ContextInput, E, R>,
): Command<Name, Input, ContextInput, E, R>;

withAlias

Added in v4.0.0 Source

Sets an alias for a command.

Details

Aliases are accepted as alternate subcommand names during parsing and are shown in help output as name, alias.

Signature

declare const withAlias: {
  (
    alias: string,
  ): <Name extends string, Input, E, R, ContextInput>(
    self: Command<Name, Input, ContextInput, E, R>,
  ) => Command<Name, Input, ContextInput, E, R>;
  <Name extends string, Input, E, R, ContextInput>(
    self: Command<Name, Input, ContextInput, E, R>,
    alias: string,
  ): Command<Name, Input, ContextInput, E, R>;
};

Sets the description for a command.

Details

Descriptions provide users with information about what the command does when they view help documentation.

Signature

declare const withDescription: {
  (
    description: string,
  ): <Name extends string, Input, E, R, ContextInput>(
    self: Command<Name, Input, ContextInput, E, R>,
  ) => Command<Name, Input, ContextInput, E, R>;
  <Name extends string, Input, E, R, ContextInput>(
    self: Command<Name, Input, ContextInput, E, R>,
    description: string,
  ): Command<Name, Input, ContextInput, E, R>;
};

withExamples

Added in v4.0.0 Source

Sets usage examples for a command.

Details

Examples are exposed in structured HelpDoc data and rendered by the default formatter in an EXAMPLES section.

Signature

declare const withExamples: {
  (examples: readonly Array<Example>): <Name extends string, Input, E, R, ContextInput>(self: Command<Name, Input, ContextInput, E, R>) => Command<Name, Input, ContextInput, E, R>;
  <Name extends string, Input, E, R, ContextInput>(self: Command<Name, Input, ContextInput, E, R>, examples: readonly Array<Example>): Command<Name, Input, ContextInput, E, R>;
}

Adds global flags to a command scope.

Details

Declared global flags apply to the command and all of its descendants.

Signature

declare const withGlobalFlags: {
  <GlobalFlags extends readonly Array<GlobalFlag<any>>>(globalFlags: GlobalFlags): <Name extends string, Input, E, R, ContextInput>(self: Command<Name, Input, ContextInput, E, R>) => Command<Name, Input, ContextInput, E, Exclude<R, ExtractGlobalFlagContext<GlobalFlags>>>;
  <Name extends string, Input, E, R, ContextInput, GlobalFlags extends readonly Array<GlobalFlag<any>>>(self: Command<Name, Input, ContextInput, E, R>, globalFlags: GlobalFlags): Command<Name, Input, ContextInput, E, Exclude<R, ExtractGlobalFlagContext<GlobalFlags>>>;
}

withHandler

Added in v4.0.0 Source

Adds or replaces the handler for a command.

Signature

declare const withHandler: {
  <A, R, E>(
    handler: (value: A) => Effect<void, E, R>,
  ): <Name extends string, XR, XE, ContextInput>(
    self: Command<Name, A, ContextInput, XE, XR>,
  ) => Command<Name, A, ContextInput, E, Exclude<R, "effect/unstable/cli/GlobalFlag/log-level">>;
  <Name extends string, A, XR, XE, R, E, ContextInput>(
    self: Command<Name, A, ContextInput, XE, XR>,
    handler: (value: A) => Effect<void, E, R>,
  ): Command<Name, A, ContextInput, E, Exclude<R, "effect/unstable/cli/GlobalFlag/log-level">>;
};

Adds flags that are inherited by subcommands.

Details

Shared flags are available to this command's handler and to descendant handlers via yield* parentCommand. Shared flags are accepted both before and after a selected subcommand name (npm-style).

Signature

declare const withSharedFlags: {
  <SharedFlags extends FlagConfig>(
    sharedFlags: SharedFlags,
  ): <Name extends string, Input, E, R, ContextInput>(
    self: Command<Name, Input, ContextInput, E, R>,
  ) => Command<
    Name,
    Simplify<Input & Simplify<{ [Key in string | number | symbol]: InferValue<SharedFlags[Key]> }>>,
    Simplify<
      ContextInput & Simplify<{ [Key in string | number | symbol]: InferValue<SharedFlags[Key]> }>
    >,
    E,
    R
  >;
  <Name extends string, Input, E, R, ContextInput, SharedFlags extends FlagConfig>(
    self: Command<Name, Input, ContextInput, E, R>,
    sharedFlags: SharedFlags,
  ): Command<
    Name,
    Simplify<Input & Simplify<{ [Key in string | number | symbol]: InferValue<SharedFlags[Key]> }>>,
    Simplify<
      ContextInput & Simplify<{ [Key in string | number | symbol]: InferValue<SharedFlags[Key]> }>
    >,
    E,
    R
  >;
};

Sets a short description for a command.

Details

Short descriptions are used when listing subcommands in help output and shell completions. If no short description is provided, the full description is used as a fallback.

Signature

declare const withShortDescription: {
  (
    shortDescription: string,
  ): <Name extends string, Input, E, R, ContextInput>(
    self: Command<Name, Input, ContextInput, E, R>,
  ) => Command<Name, Input, ContextInput, E, R>;
  <Name extends string, Input, E, R, ContextInput>(
    self: Command<Name, Input, ContextInput, E, R>,
    shortDescription: string,
  ): Command<Name, Input, ContextInput, E, R>;
};

Adds subcommands to a command, creating a hierarchical command structure.

Details

Subcommands can access their parent's parsed configuration by yielding the parent command within their handler. This enables shared parent flags that affect all subcommands.

Signature

declare const withSubcommands: {
  <Subcommands extends readonly Array<SubcommandEntry>>(subcommands: Subcommands): <Name extends string, Input, E, R, ContextInput>(self: Command<Name, Input, ContextInput, E, R>) => Command<Name, Simplify<Input | ContextInput>, ContextInput, E | Error<ExtractSubcommand<Subcommands[number]>>, R | Exclude<Services<ExtractSubcommand<Subcommands[number]>>, CommandContext<Name>>>;
  <Name extends string, Input, E, R, ContextInput, Subcommands extends readonly Array<SubcommandEntry>>(self: Command<Name, Input, ContextInput, E, R>, subcommands: Subcommands): Command<Name, Simplify<Input | ContextInput>, ContextInput, E | Error<ExtractSubcommand<Subcommands[number]>>, R | Exclude<Services<ExtractSubcommand<Subcommands[number]>>, CommandContext<Name>>>;
}

Constructors

make

Added in v4.0.0 Source

Creates a Command from a name, an optional configuration, and an optional handler.

Details

Use withDescription and related metadata combinators to add help text. The overloads support simple commands, configured commands, and commands with effectful handlers.

Signature

declare const make: {
  <Name extends string>(name: Name): Command<Name, {}, {}, never, never>;
  <Name extends string, Config extends Config>(
    name: Name,
    config: Config,
  ): Command<
    Name,
    Simplify<{ [Key in string | number | symbol]: InferValue<Config[Key]> }>,
    {},
    never,
    never
  >;
  <Name extends string, Config extends Config, R, E>(
    name: Name,
    config: Config,
    handler: (
      config: Simplify<{ [Key in string | number | symbol]: InferValue<Config[Key]> }>,
    ) => Effect<void, E, R>,
  ): Command<
    Name,
    Simplify<{ [Key in string | number | symbol]: InferValue<Config[Key]> }>,
    {},
    E,
    Exclude<R, "effect/unstable/cli/GlobalFlag/log-level">
  >;
};

Guards

isCommand

Added in v4.0.0 Source

Returns true if the provided value is a Command.

Gotchas

This checks for the Command type-id property; it does not validate the full command shape.

Signature

declare function isCommand(u: unknown): u is Any;

Models

Command interface

Added in v4.0.0 Source

Represents a CLI command with its configuration, handler, and metadata.

Details

Commands are the core building blocks of CLI applications. They define:

- The command name and description - Configuration including flags and arguments - Handler function for execution - Optional subcommands for hierarchical structures

Signature

interface Command<in out Name extends string, in Input, out ContextInput = {}, out E = never, out R = never> extends Effect<ContextInput, never, CommandContext<Name>> {
  readonly "~effect/cli/Command": Variance<Input, E, R>;
  readonly alias: string | undefined;
  readonly annotations: Context<never>;
  readonly description: string | undefined;
  readonly examples: readonly Array<Example>;
  readonly name: Name;
  readonly shortDescription: string | undefined;
  readonly subcommands: readonly Array<{
    readonly commands: readonly [Any, Any];
    readonly group: string | undefined;
  }>;
  readonly unlisted: boolean;
}

CommandContext interface

Added in v4.0.0 Source

Service context for a specific command, enabling subcommands to access their parent's parsed configuration.

Details

When a subcommand handler needs access to flags or arguments from a parent command, it can yield the parent command directly to retrieve its config. This is powered by Effect's service system - each command automatically creates a service that provides its parsed input to child commands.

Signature

interface CommandContext<Name extends string> {
  readonly _: typeof _;
  readonly name: Name;
}

ParsedTokens interface

Added in v4.0.0 Source

Represents the parsed tokens from command-line input before validation.

Signature

interface ParsedTokens {
  readonly arguments: readonly Array<string>;
  readonly errors?: readonly Array<UnrecognizedOption | DuplicateOption | MissingOption | MissingArgument | UnexpectedArgument | InvalidValue | UnknownSubcommand | UserError>;
  readonly flags: Record<string, ReadonlyArray<string>>;
  readonly subcommand: Option<{
    readonly name: string;
    readonly parsedInput: ParsedTokens;
  }>;
}

Other

Command

Added in v4.0.0 Source

Companion namespace containing type-level helpers and configuration shapes used by Command.

Providing Services

provide

Added in v4.0.0 Source

Provides the handler of a command with the services produced by a layer that optionally depends on the command-line input to be created.

Signature

declare const provide: {
  <Input, LR, LE, LA>(layer: Layer<LA, LE, LR> | (input: Input) => Layer<LA, LE, LR>, options?: {
    readonly local?: boolean;
  }): <Name extends string, E, R, ContextInput>(self: Command<Name, Input, ContextInput, E, R>) => Command<Name, Input, ContextInput, LE | E, LR | Exclude<R, LA>>;
  <Name extends string, Input, E, R, ContextInput, LA, LE, LR>(self: Command<Name, Input, ContextInput, E, R>, layer: Layer<LA, LE, LR> | (input: Input) => Layer<LA, LE, LR>, options?: {
    readonly local?: boolean;
  }): Command<Name, Input, ContextInput, E | LE, LR | Exclude<R, LA>>;
}

Provides the handler of a command with the service produced by an effect that optionally depends on the command-line input to be created.

When to use

Use to acquire a service effectfully for each command run, optionally using parsed command input.

See

Signature

declare const provideEffect: {
  <I, S, Input, R2, E2>(service: Key<I, S>, effect: Effect<S, E2, R2> | (input: Input) => Effect<S, E2, R2>): <Name extends string, E, R, ContextInput>(self: Command<Name, Input, ContextInput, E, R>) => Command<Name, Input, ContextInput, E2 | E, R2 | Exclude<R, I>>;
  <Name extends string, Input, E, R, ContextInput, I, S, R2, E2>(self: Command<Name, Input, ContextInput, E, R>, service: Key<I, S>, effect: Effect<S, E2, R2> | (input: Input) => Effect<S, E2, R2>): Command<Name, Input, ContextInput, E | E2, R2 | Exclude<R, I>>;
}

Allows for execution of an effect, which optionally depends on command-line input to be created, prior to executing the handler of a command.

Signature

declare const provideEffectDiscard: {
  <_, Input, E2, R2>(effect: Effect<_, E2, R2> | (input: Input) => Effect<_, E2, R2>): <Name extends string, E, R, ContextInput>(self: Command<Name, Input, ContextInput, E, R>) => Command<Name, Input, ContextInput, E2 | E, R2 | R>;
  <Name extends string, Input, E, R, ContextInput, _, E2, R2>(self: Command<Name, Input, ContextInput, E, R>, effect: Effect<_, E2, R2> | (input: Input) => Effect<_, E2, R2>): Command<Name, Input, ContextInput, E | E2, R | R2>;
}

provideSync

Added in v4.0.0 Source

Provides the handler of a command with the implementation of a service that optionally depends on the command-line input to be constructed.

When to use

Use when a command handler needs a pure service implementation, optionally derived from the parsed command input.

Signature

declare const provideSync: {
  <I, S, Input>(service: Key<I, S>, implementation: S | (input: Input) => S): <Name extends string, E, R, ContextInput>(self: Command<Name, Input, ContextInput, E, R>) => Command<Name, Input, ContextInput, E, Exclude<R, I>>;
  <Name extends string, Input, E, R, ContextInput, I, S>(self: Command<Name, Input, ContextInput, E, R>, service: Key<I, S>, implementation: S | (input: Input) => S): Command<Name, Input, ContextInput, E, Exclude<R, I>>;
}

Running

run

Added in v4.0.0 Source

Runs a command using the arguments supplied by the Stdio service.

When to use

Use when command-line arguments should come from Stdio at the application entry point.

See

  • runWith for running a command with an explicit argument array

Signature

declare const run: {
  (config: {
    readonly version: string;
  }): <Name extends string, Input, E, R, ContextInput>(
    command: Command<Name, Input, ContextInput, E, R>,
  ) => Effect<void, CliError | E, Environment | R>;
  <Name extends string, Input, E, R, ContextInput>(
    command: Command<Name, Input, ContextInput, E, R>,
    config: {
      readonly version: string;
    },
  ): Effect<void, CliError | E, Environment | R>;
};

runWith

Added in v4.0.0 Source

Runs a command with explicitly provided arguments instead of using arguments from Stdio.

When to use

Use when you need to test CLI applications or programmatically execute commands with specific arguments.

Signature

declare function runWith<Name extends string, Input, E, R, ContextInput>(command: Command<Name, Input, ContextInput, E, R>, config: {
  readonly version: string;
}): (input: readonly Array<string>) => Effect<void, CliError | Exclude<E, QuitError>, Environment | R>

wizard

Added in v4.0.0 Source

Interactively constructs command-line arguments for a command.

Details

The returned arguments include the command name and can be inspected, modified, or passed to another command runner by the caller.

Signature

declare function wizard<Name extends string, Input, E, R, ContextInput>(command: Command<Name, Input, ContextInput, E, R>, options?: {
  readonly prefix?: readonly Array<string>;
}): Effect<Array<string>, QuitError | CliError, Environment>

Utility Types

Environment type

Added in v4.0.0 Source

Services required by CLI parsing and execution.

Details

This includes file-system and path services for arguments, terminal and stdio services for running commands, and child-process spawning for process-related CLI features.

Signature

type Environment =
  | FileSystem.FileSystem
  | Path.Path
  | Terminal.Terminal
  | ChildProcessSpawner
  | Stdio.Stdio;

Error type

Added in v4.0.0 Source

A utility type to extract the error type from a Command.

Signature

type Error<C> =
  C extends Command<
    infer _Name,
    infer _Input,
    infer _ContextInput,
    infer _Error,
    infer _Requirements
  >
    ? _Error
    : never;

Services type

Added in v4.0.0 Source

A utility type to extract the required services type from a Command.

Signature

type Services<C> =
  C extends Command<
    infer _Name,
    infer _Input,
    infer _ContextInput,
    infer _Error,
    infer _Requirements
  >
    ? _Requirements
    : never;