Skip to content

Consistent help behavior regardless of --help position #12

Description

@taras

Problem

Currently, configliere's help detection only triggers when --help is the first argument after the command name. When --help appears later in argv, the parser continues normally, which can cause validation errors or require consumers to manually detect help in unparsed remainder.

Example

const parser = program({
  name: "myapp",
  config: commands({
    run: {
      description: "Run command",
      ...object({
        config: { description: "Config file", ...field(z.string().optional()) },
        suite: { description: "Test suite", ...field(z.string(), cli.argument()) },
      }),
    },
  }),
});

// --help first: works, returns help text
parser.parse({ args: ["run", "--help", "--config", "foo.json"], envs: [] });
// Result: { ok: true, value: { config: { help: true, text: "..." } } }

// --help later: fails validation (suite required)
parser.parse({ args: ["run", "--config", "foo.json", "--help"], envs: [] });
// Result: { ok: false, error: "suite: required" }

The problem for consumers

Tools that want "source-sensitive help" (showing where config values come from) need to:

  1. Parse --config to load the config file
  2. Pass config values to the help parser
  3. Display help with source annotations like [file: verbose=true]

But if --help must come first for help to trigger, the config path is never parsed, and source-sensitive help is impossible in that case.

Current workaround

We manually check if remainder.args[0] === "--help" after our own parsing phase, then construct synthetic args with --help first to trigger configliere's help path. This:

  • Duplicates configliere's internal help detection logic
  • Creates position-dependent behavior (same command, different help output)
  • Is fragile if configliere's help detection changes

Desired behavior

When --help appears anywhere in args:

  1. Still parse all preceding options (so --config value is available)
  2. Set the help: true flag
  3. Skip validation of required fields
  4. Return help text with any available source annotations

This would make help behavior consistent regardless of where the user places --help:

run --help --config foo.json    # same result as
run --config foo.json --help    # this

Possible implementation

  • Scan for --help/-h anywhere in args before parsing
  • If found, parse in "help mode" — collect values but skip validation
  • Return help text with source annotations for any values that were parsed

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