Skip to content

unstable/cli: Allow customizing built-in global flags in runWith #6151

@craigsmitham

Description

@craigsmitham

Summary

runWith hardcodes GlobalFlag.BuiltIns in three places, making it impossible to exclude or replace individual built-in global flags like --log-level. CLIs that implement their own verbosity model (e.g. --verbose / --quiet / --debug boolean flags) end up with two overlapping verbosity controls in --help, which is confusing for users.

Current behavior

runWith accepts a config with only version:

export const runWith = <...>(
  command: Command<...>,
  config: {
    readonly version: string
  }
): (input: ReadonlyArray<string>) => Effect.Effect<...>

GlobalFlag.BuiltIns is hardcoded at three call sites:

  • showHelp (Command.ts:1226)
  • getGlobalFlagsForCommandTree (Command.ts:1335)
  • getGlobalFlagsForCommandPath (Command.ts:1347)

There is no way to filter, replace, or exclude individual built-ins.

Proposed change

Add an optional flags field to the config parameter:

export const runWith = <...>(
  command: Command<...>,
  config: {
    readonly version: string
    readonly flags?: ReadonlyArray<GlobalFlag.GlobalFlag<any>>
  }
): (input: ReadonlyArray<string>) => Effect.Effect<...>

When provided, config.flags replaces GlobalFlag.BuiltIns at all three call sites. When omitted, behavior is unchanged.

Use case

Our CLI defines --verbose / -v, --quiet / -q, and --debug as boolean global flags that resolve to a VerbosityLevel union (quiet | normal | verbose | debug). The built-in --log-level flag overlaps with this, creating two competing verbosity controls in --help output. We'd like to exclude LogLevel while keeping Help, Version, and Completions:

import { GlobalFlag } from "effect/unstable/cli"

const flags = GlobalFlag.BuiltIns.filter((f) => f !== GlobalFlag.LogLevel)

const run = Command.runWith(rootCommand, {
  version: "1.0.0",
  flags,
})

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions