Fix: print usage for a bare adk invocation instead of only the version - #597
Open
AmaadMartin wants to merge 2 commits into
Open
Fix: print usage for a bare adk invocation instead of only the version#597AmaadMartin wants to merge 2 commits into
AmaadMartin wants to merge 2 commits into
Conversation
added 2 commits
August 8, 2026 10:47
The root commander command had an unconditional action handler that printed the version, so bare `adk` answered with a version string and never listed its subcommands. A first-time user then has no way to discover the tool from its own front door. Branch the handler on the --version flag and fall through to the root help. The help goes to stdout and the process still exits 0, because a bare `adk` is a discovery request rather than a usage error. `outputHelp()` is what keeps that contract; `help()` would raise a CommanderError. Also rename the program from 'ADK CLI' to 'adk' so the usage line the user now sees names the actual binary (and every subcommand's usage line reads 'adk web ...' rather than 'ADK CLI web ...').
…rError
Replace the hand-rolled {code?, exitCode?} structural type with the class
commander exports for exactly this. Both fields are required on the real
type, so the unknown-subcommand assertions no longer need optional
chaining; narrow the possibly-undefined result with expect.fail so a
missing throw reports as a real assertion failure.
AmaadMartin
force-pushed
the
fix/adk-js-bare-invocation-usage
branch
from
August 8, 2026 17:53
11341be to
43ad09c
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Please ensure you have read the contribution guide before creating a pull request.
Link to Issue or Description of Change
N/A
Problem: The root commander command has an unconditional action handler that prints the version. Bare
adktherefore answers with a version string and never lists its subcommands, so the CLI has no discovery affordance at its own front door. Every generated usage line also readsUsage: ADK CLI web ..., which names no runnable command.Solution: The handler now branches on the
--versionflag and falls through toprogram.outputHelp(). The help goes to stdout and the process exits 0, because a bareadkis a discovery request rather than a usage error. I also renamed the program toadk, so every usage line names the real binary.Why stdout and exit 0
adkexits 0 with help on stdout, butadk deploystill exits 1 with help on stderr. The asymmetry is deliberate:-v/--version. Printing help and returning normally is the natural expression there, and it exits 0.gh(0),npm(1) andgit(1) all print the usage block on stdout for a bare invocation. The ecosystem is split on the exit code but not on the stream. Exit 0 is also the less breaking option, since bareadkexits 0 today.Rejected alternative: stderr and exit 1, for symmetry with the groups. Please push back if you prefer it.
outputHelp()is load-bearing.help()raises aCommanderErrorthrough commander's exit handling, andhelp({error: true})also redirects to stderr and exits 1.Notes for the reviewer
no_args_is_helpdefault. That claim was wrong and I removed it. The default is real, but click 8.2.0 changed the exit code to 2 and emits the usage on stderr (Help shown via no_args_is_help results in exit code 2, was 0 pallets/click#1489), and adk-python resolves to click 8.2+. The Python CLI's bare invocation is a usage error today, which is the opposite of this contract.adkbreaks.adk --versionis the documented spelling and is unaffected, and the exit code stays 0.-vmeans--versionon the root and--verboseon the subcommands, and the root wins, soadk web -vsilently swallows the flag. It predates this change and is queued separately.outputHelpvshelp) and moved the group-asymmetry rationale here, where the plan also requires it.fix/cli-root-help-commandaddsprogram.helpCommand(true);fix/cli-group-bare-invocation-contractadds a comment on thedeploygroup. Both merge cleanly against this except for thecommanderimport line, which all three touch. Whoever lands second resolves it to the union.Testing Plan
Please describe the tests that you ran to verify your changes. This is required for all PRs that are not small documentation or typo fixes.
Unit Tests:
[x] I have added or updated unit tests for my change.
[x] All unit tests pass locally.
npx vitest run --project unit:dev dev/test/cli/cli_test.ts-> 29/29 pass.One new
describe('bare invocation')block with three cases: bareadkprints the usage and all six subcommands and no version;-vand--versionprint only the version; an unknown subcommand exits 1 with nothing on stdout. The block sits beforedescribe('command: version')to avoid the insertion point another in-flight branch uses. No existing test, mock or hook was modified or deleted, and the diff on the test file is additions only.Coverage of the new code is 100% line and branch, read from
coverage-final.json: both arms of the one new branch are hit, 4 times (version) and 1 time (bare).Mutation proof. Every new test fails against mutated source:
if (true || options.version), i.e. today's behaviourexpected '' to contain 'Usage: adk'if (false && options.version)expected "log" to be called with arguments: [ '1.0.0-test' ](the new test and the pre-existing version test)new Command('ADK CLI')expected 'Usage: ADK CLI [options] [command]\n…' to contain 'Usage: adk'program.allowExcessArguments(true)on the rootexpected commander to reject an unknown subcommandManual End-to-End (E2E) Tests:
Please provide instructions on how to manually test your changes, including any necessary setup or configuration.
All six behave as listed. The bare output is byte-identical to
--help, and it survives2>/dev/null, which proves it goes to stdout.Also run on this commit:
npm run lintclean,npm run format:checkclean,npx tsc --noEmitreports 0 errors.Checklist
[x] I have read the CONTRIBUTING.md document.
[x] I have performed a self-review of my own code.
[x] I have commented my code, particularly in hard-to-understand areas.
[x] I have added tests that prove my fix is effective or that my feature works.
[x] New and existing unit tests pass locally with my changes.
CI note
The first windows run failed on
tests/integration/app_loader/app_loader_test.ts("discover apps vs agents"), which timed out against its own 40s budget. That test is a known flake and this branch does not touch it: the diff is two CLI files, ubuntu and macos passed the same commit, and 3138 of 3139 tests passed on windows. Four open PRs already target this flake, including #247 ("stop app_loader discovery test timing out on Windows/macOS CI"). The job passed on re-run, and all three platforms are now green.