cli icon indicating copy to clipboard operation
cli copied to clipboard

chore: Command Configs

Open reggi opened this issue 1 month ago • 2 comments

Command-Specific Flags Implementation Checklist

This PR enables commands to define their own distinct flags separate from global configuration, eliminating the need for verbose prefixed flags like --init-name and allowing cleaner command-specific options.

Key Features

  • New flags configuration source - Adds a dedicated layer in the config hierarchy for command-specific flags without modifying existing sources
  • Command definition merging - Implements loadCommand() method to merge command-specific definitions with global definitions
  • Warning deduplication - Captures and deduplicates warnings during initial config load to prevent duplicate messages across sources
  • Synchronous design - No new async calls or config instances, integrates seamlessly with existing load flow
  • Clean flag naming - Enables commands to use simple flags (e.g., --name) instead of verbose prefixed versions (e.g., --init-name)

Implementation Tasks

  • [x] Add flags to config source hierarchy (between env and cli)
  • [x] Implement loadCommand(definitions) method for dynamic definition merging
  • [x] Add warning capture system (#warnings array) to delay logging until after command load
  • [x] Implement removeWarnings(types) to clear superseded warnings
  • [x] Implement #deduplicateWarnings() to prevent duplicate warnings
  • [x] Add logWarnings() method to flush captured warnings
  • [x] Update type/default merging to support command-specific definitions
  • [x] Handle exclusive flag validation across merged definitions
  • [x] Update checkUnknown() to recognize both cli and flags sources
  • [x] Test command-specific flag parsing and precedence

reggi avatar Nov 24 '25 14:11 reggi

Now just running npm run prepack will make sure all commands have a .md file and add it to nav.yml and generate a md with flags populated example below:

  ---
  title: npm-tset
  section: 1
  description: A test command with custom flags
  ---

  ### Synopsis

  ```bash
  npm tset [options]
  ```

  Note: This command is unaware of workspaces.

  ### Description

  A test command with custom flags

  ### Configuration

  #### `say`

  * Default: "hello"
  * Type: String

  What to say when running the test command



  ### See Also

  * [npm help config](/commands/npm-config)

reggi avatar Dec 05 '25 19:12 reggi

yay! (seems more like a feat than a chore tho :-p)

so does this mean i'll be able to set a top-level config value, but then override it for a specific command?

ljharb avatar Dec 05 '25 20:12 ljharb

@ljharb

yay! (seems more like a feat than a chore tho :-p)

so does this mean i'll be able to set a top-level config value, but then override it for a specific command?

I put it as a chore because It's not really a customer facing thing. It just allows commands to not need to have prefix flags like what init did with --init-name and we can just do --name...

reggi avatar Dec 12 '25 17:12 reggi

It has to be at least a fix since it affects the published code. chore is reserved for things that shouldn't trigger a new published version.

wraithgar avatar Dec 12 '25 17:12 wraithgar

so does this mean i'll be able to set a top-level config value, but then override it for a specific command?

No it means we can define a config that only is for a specific command. Obviously these couldn't go into config files (yet?). This will allow commands to have overlapping names in config that have wholly separate configs (i.e. --name in npm init could have different rules than --name in npm token create)

wraithgar avatar Dec 12 '25 17:12 wraithgar

ah ok, gotcha. i'm not sure how name in npmrc would work tho in that example, if there's two distinct sets of possible values for that config key?

meaning, merely adding a command line config whose acceptable values differ across commands would make that config name poisoned (in npmrc or env vars) until the capability exists for users to override a config value more granularly down to a specific command

ljharb avatar Dec 12 '25 20:12 ljharb

@ljharb this PR adds command-level configs just for flags (no .npmrc support, and that's intentional) for new commands. If / when we want that we could go with ini "sections" syntax like this:

[command-foo]
name=hello world

[command-bar]
name=true

reggi avatar Dec 15 '25 15:12 reggi

right - but as soon as you add that example without npmrc/env var support, the string "name" in npmrc becomes broken. Meaning, it's not just about new commands, it's that adding any new config key becomes a breaking change, because someone could have it in their env or npmrc.

ljharb avatar Dec 15 '25 15:12 ljharb