Skip to content

feat: implement progressive CLI help disclosure and dynamic deploy help#10772

Merged
joehan merged 13 commits into
mainfrom
improve-cli-help
Jul 15, 2026
Merged

feat: implement progressive CLI help disclosure and dynamic deploy help#10772
joehan merged 13 commits into
mainfrom
improve-cli-help

Conversation

@joehan

@joehan joehan commented Jul 7, 2026

Copy link
Copy Markdown
Member

Description

Revamping the --help and firebase help command to use progressive disclosure. Instead of dumping a massive list of commands all at once, you can navigate this layer by layer so that there is not a ton of irrelevant info flooding the terminal (or context).

I also cleaned up some of our Winston logging transport initialization logic - it was spread our over a few places (and was happening late enough to miss some errors early in the flow). Now, it lives at the main entry point for the cli binary.

I also ran our eval suite before and after this change - in cases where the --help command was run, we saw significant performance improvements:

Averages Across Help-Executing Cases

Metric BEFORE Run AFTER Run Change / Diff (%)
Average Turns 45.1 turns 30.2 turns -33.0%
Average Duration 72.2s 60.5s -16.2%
Average Tokens 128.2k 97.6k -23.9%

Testing

Before this change, firebase --help would print every single command, and firebase <command> help would print the help text for just that command. There was no support for firebase <namespace> --help - doing so would just give you a 'command not found error'

Some examples of the new behavior - at the top level, --help just returns all of the top level namespaces:

$ firebase --help
Usage: firebase [options] [command]
Options:
  -V, --version                        output the version number
  -P, --project <alias_or_project_id>  the Firebase project to use for this command
  --account <email>                    the Google account to use for authorization
  -j, --json                           output JSON instead of text, also triggers non-interactive mode
  --token <token>                      DEPRECATED - will be removed in a future major version
  --non-interactive                    error out of the command instead of waiting for prompts
  -i, --interactive                    force prompts to be displayed
  --debug                              print verbose debug output and keep a debug log file
  -c, --config <path>                  path to the firebase.json file to use for configuration
  -h, --help                           display help for command
Commands:
  deploy [options]                     deploy code and assets to your Firebase project
  ext                                  display information on how to use ext commands
  help [command]                       display help information
  init [feature]                       interactively configure the current directory as a Firebase project
  login [options]                      log the CLI into Firebase
  logout [email]                       log the CLI out of Firebase
  mcp|experimental:mcp                 Run the multi-modal conversational platform (MCP) server.
  open [link]                          quickly open a browser to relevant project resources
  serve [options]                      start a local server for your static assets
  target [type]                        display configured deploy targets for the current project
  use [options] [alias_or_project_id]  set an active Firebase project for your working directory
  appdistribution                      manage App Distribution resources
  apptesting                           manage apptesting resources
  apps                                 manage Firebase apps
  auth                                 manage Firebase Auth
  crashlytics                          manage Crashlytics symbols and mappings
  database                             manage Realtime Database
  emulators                            start and manage local Firebase emulators
  experiments                          enable and disable CLI experiments
  firestore                            manage Cloud Firestore resources
  functions                            manage Cloud Functions
  hosting                              manage Firebase Hosting sites and channels
  apphosting                           manage App Hosting resources
  projects                             manage Firebase projects
  remoteconfig                         manage Remote Config
  setup                                manage setup resources
  dataconnect                          manage Data Connect resources
  studio                               manage studio resources
To see more about a specific namespace or command, run:
  firebase <namespace|command> --help

To dig deeper you request help on the hosting namespace. It prints only the hosting subcommands and sub-namespaces (like channel and sites), filtering out all other unrelated CLI commands:

$ firebase hosting --help
Usage: firebase hosting [options] [command]
manage Firebase Hosting sites and channels
Options:
  -h, --help                              display help for command
Commands:
  hosting:clone <source> <targetChannel>  clone a version from one site to another
  hosting:disable [options]               stop serving web traffic to your Firebase Hosting site
  hosting:channel                         manage hosting:channel resources
  hosting:sites                           manage hosting:sites resources
To see more about a specific command, run:
  firebase hosting:<command> --help

This applies for all namespace levels - for example, running help on hosting:channel lists all leaf commands scoped strictly under that namespace:

$ firebase hosting:channel --help
Usage: firebase hosting:channel [options] [command]
manage hosting:channel resources
Options:
  -h, --help                                    display help for command
Commands:
  hosting:channel:create [options] [channelId]  create a Firebase Hosting channel
  hosting:channel:delete [options] <channelId>  delete a Firebase Hosting channel
  hosting:channel:deploy [options] [channelId]  deploy to a specific Firebase Hosting channel
  hosting:channel:list [options]                list all Firebase Hosting channels for your project
  hosting:channel:open [options] [channelId]    opens the URL for a Firebase Hosting channel
To see more about a specific command, run:
  firebase hosting:channel:<command> --help

I also improved the flow for deploy - that is one of our most complicated comands, and it previously offered no meaningful help:
Now, it offers details about all the targets:

$ firebase deploy--help
Usage: firebase deploy [options]
deploy code and assets to your Firebase project
Options:
-f, --force              delete Cloud Functions missing from the current
                         working directory and bypass interactive prompts
-p, --public <path>      override the Hosting public directory specified in
                         firebase.json
-m, --message <message>  an optional message describing this deploy
--only <targets>         only deploy to specified, comma-separated targets
                         ...
-h, --help               display help for command
Deploy targets include:
hosting        Deploys assets, redirects, rewrites, and headers configuration from your project's firebase.json.
database       Deploys security rules defined in your project's firebase.json.
firestore      Deploys security rules and indexes defined in your project's firebase.json.
functions      Deploys functions from the functions directory. Supports filtering function deploys:
    --only functions:func1,functions:func2 (scoped function deploy)
    --only functions:group.subgroup (scoped by export group)
    --only functions:codebase:func (scoped by codebase and function)
storage        Deploys security rules for Cloud Storage buckets defined in your project's firebase.json.
remoteconfig   Deploys templates defined in your project's firebase.json.
extensions     Deploys configuration changes to your installed Extension instances.
dataconnect    Deploys Data Connect services, schemas, and connectors. Supports filtering:
    --only dataconnect:serviceId
    --only dataconnect:serviceId:connectorId
    --only dataconnect:serviceId:schema
apphosting     Deploys Next.js / Angular / Astro app backends. Supports configuration in apphosting.yaml.
auth           Deploys configuration settings for Firebase Authentication providers.
To deploy specific targets, use `--only` followed by a comma-separated list of targets.
For example, firebase deploy --only hosting,firestore.
To see detailed setup and configuration details for a specific target, run:
firebase help deploy:<target>

And, you can view specific details about how to use a target:

$ firebase deploy:hosting--help
Detailed deploy information for hosting:
Firebase Hosting deploys web assets, redirects, rewrites, and header configurations.
Single site configuration in firebase.json:
{
"hosting": {
  "public": "public",
  "ignore": [
    "firebase.json",
    "**/.*",
    "**/node_modules/**"
  ],
  "rewrites": [
    { "source": "**", "destination": "/index.html" }
  ]
}
}
Multiple sites configuration (by site ID or deploy target):
{
"hosting": [
  {
    "site": "my-site-id",
    "public": "dist"
  },
  {
    "target": "my-site-target",
    "public": "build"
  }
]
}

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces progressive help for CLI commands, dynamically registering intermediate namespaces and filtering subcommands. It also refactors deploy targets to centralize their metadata, enabling dynamic help generation and detailed target-specific help via firebase help deploy:<target>. The review feedback highlights several opportunities to align with the repository style guide, such as replacing console.log with the central logger, avoiding any type escapes with proper interfaces, correcting an inaccurate reference to database indexes, and improving type safety in dynamic imports to prevent potential prototype pollution.

Comment thread src/bin/progressiveHelp.ts
Comment thread src/bin/progressiveHelp.ts Outdated
Comment thread src/bin/progressiveHelp.ts
Comment thread src/bin/progressiveHelp.ts
Comment thread src/deploy/database/index.ts Outdated
Comment thread src/commands/help.ts Outdated
Comment thread src/commands/deploy.ts
@joehan joehan requested a review from chkuang-g July 8, 2026 22:21
@chkuang-g

Copy link
Copy Markdown
Contributor

Could you provide some example about how CLI help looks like now? It is a bit hard to comprehend by reading your code.

Please provide some CLI example and their output.

Thank you

@joehan

joehan commented Jul 9, 2026

Copy link
Copy Markdown
Member Author

Could you provide some example about how CLI help looks like now? It is a bit hard to comprehend by reading your code.

Please provide some CLI example and their output.

Thank you

Done - added a bunch of example output to the description.

@joehan joehan removed the request for review from chkuang-g July 14, 2026 19:44
Comment thread src/bin/cli.ts Outdated
Comment thread src/bin/cli.ts Outdated
Comment thread src/bin/progressiveHelp.spec.ts Outdated
Comment thread src/bin/progressiveHelp.spec.ts Outdated
Comment thread src/bin/progressiveHelp.spec.ts Outdated
Comment thread src/deploy/extensions/index.ts Outdated
"Configuration format in firebase.json:\n" +
"{\n" +
' "extensions": {\n' +
' "storage-resize-images": "extensions/storage-resize-images.env"\n' +

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is wrong. The expected format is "my-extension-instance-id": "firebase/storage-resize-images@^0.1.0"

Comment thread src/deploy/firestore/index.ts
Comment thread src/deploy/hosting/index.ts Outdated
Comment thread src/deploy/remoteconfig/index.ts Outdated
Comment thread src/logger.ts Outdated
Comment thread src/commands/deploy.ts Outdated
Comment thread src/commands/deploy.ts
.before(requireConfig)
.before((options: Options) => {
options.filteredTargets = filterTargets(options, VALID_DEPLOY_TARGETS);
options.filteredTargets = filterTargets(options, [...VALID_DEPLOY_TARGETS]);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why this change?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Super nitty thing that jetski caught - mutating this const array was a potential future footgun

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think filterTargets mutates the input. The right way is to fix the typing for filterTargets so it takes a const array, to signify that it doesn't mutate the input. This should fix Jetski warnings and also improve the documentation and may even prevent future TypeScript warnings / errors. Anyway this is a super nit and we can wait and see if we will touch this code again

Comment thread src/commands/help.ts Outdated
Comment thread src/commands/deploy.ts Outdated
Comment thread src/commands/help.ts Outdated
Comment thread src/commands/help.ts Outdated
Comment thread src/deploy/firestore/index.ts Outdated
Comment thread src/deploy/database/index.ts Outdated
Comment thread src/deploy/database/index.ts Outdated
@joehan joehan merged commit 58e5520 into main Jul 15, 2026
52 of 53 checks passed
@joehan joehan deleted the improve-cli-help branch July 15, 2026 22:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants