Discover subcommands in k6 x - #5972
Merged
Merged
Conversation
Introduces K6_PROVISION_CATALOG_CACHE_AGE so callers can tune how long the on-disk k6 extension registry catalog is treated as fresh. The knob is read by the upcoming `k6 x` registry stub renderer; declaring it first keeps the surface change isolated.
Until now the `k6 x` help only listed baked-in extension subcommands, so users had no way to discover what else the wider catalog offered. Read the on-disk catalog cache during command tree construction and register a cobra stub for every advertised subcommand not already baked in, with an annotation marking each one as registry-sourced. Invoking a stub falls through to the regular provisioning path.
The new registry stubs added in the previous commit are real cobra children, so the existing completion detector — which only fired when cobra fell back to `x` itself — silently skipped them and never triggered provisioning for stub names. Match the stub annotation explicitly so `k6 __complete x <stub> ...` provisions the extension instead of returning nothing.
With only cache-backed rendering, fresh installs and CI runs never see registry-advertised subcommands until something else seeds the cache. Fetch the catalog over HTTP on miss with a 10s timeout, write the response back to the cache, and recover the parsed subcommands for the same call. K6_PROVISION_CATALOG_URL lets tests and developers redirect the fetch; the shared test harness points it at an unreachable address so suites stay off the real registry.k6.io by default.
The first `k6 x` invocation on a fresh install pauses for up to ten seconds while the catalog downloads, with no indication anything is happening. Print a single `Loading the subcommand list...` line on stderr around the fetch and clear it afterwards on TTYs (or newline-separate it on plain pipes) so help output renders cleanly.
Cache and fetch failures previously vanished into silent swallowing, leaving users with no way to tell why `k6 x` showed an unexpectedly short list. Emit each at debug so -v surfaces them while normal stderr stays clean.
Lock in that `k6 x` lists registry-advertised subcommands when the catalog is reachable, falls back silently when it's unreachable, and stays quiet when AutoExtensionResolution is disabled. Adds an httptest helper plus a small fixture catalog reused by upcoming completion tests.
Shell completion must never hit the network: TAB feedback would freeze for ten seconds on a slow link. Lock down both directions of the gate: when the on-disk catalog cache exists, completion surfaces the stub names; when it doesn't, completion returns no stub names instead of fetching. An unreachable catalog URL stands in as the tripwire — any accidental fetch would surface as a hang.
When the cache promotes alpha to a registry stub, cobra finds it as a real child of `x` instead of falling through, so the master detection path — which only fired for unknown names — would otherwise skip provisioning. Lock in that completion under a stub still reports the extension name for the dependency check.
inancgumus
temporarily deployed
to
azure-trusted-signing
May 12, 2026 22:23 — with
GitHub Actions
Inactive
inancgumus
temporarily deployed
to
azure-trusted-signing
May 12, 2026 22:25 — with
GitHub Actions
Inactive
szkiba
previously approved these changes
May 13, 2026
szkiba
left a comment
Contributor
There was a problem hiding this comment.
I like the solution, I just made two small (nit) comments.
K6_PROVISION_CATALOG_CACHE_AGE was non-standard. TTL is the universally understood term for how long a cached value stays fresh. Co-authored-by: Iván Szkiba <szkiba@users.noreply.github.com>
inancgumus
marked this pull request as ready for review
May 13, 2026 18:17
inancgumus
temporarily deployed
to
azure-trusted-signing
May 13, 2026 18:21 — with
GitHub Actions
Inactive
inancgumus
temporarily deployed
to
azure-trusted-signing
May 13, 2026 18:23 — with
GitHub Actions
Inactive
szkiba
approved these changes
May 14, 2026
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.
What?
k6 xlists subcommands (baked + advertised by the registry (official and community)).Note
We retrieve the catalog from the network (10s timeout) and cache it.
TAB completions
Tab completion lists the same set, but only when the catalog is already cached locally. Hitting
<TAB>must never block on the network, so until a priork6 xrun populates the cache, completion returns only what's baked into the binary.Why?
AI agents driving a k6 binary can't directly introspect subcommands; they're blind to extensions. As agentic workflows grow, the binary needs to answer the question "what can you do?" on its own.
Notes
All subcommands render in a single
Available Commands:block. Cobra v1.4 lacks a command-group API, and tagging them by tier would require a Cobra bump or a custom help template for a marginal UX gain.k6 x explorecovers more than subcommands (all extensions), requires provisioning before it can run, and folding it into k6 would mean a stable internal API across versions, help address output mismatches with every other built-in command, and changes (+exports) insidexk6-subcommand-exploreitself. A static, generated built-in extensions list was also considered a fallback and rejected: it would go stale until the next k6 release and would be out of sync.Follow-up
shortfield per entry,k6 xwill surface it without a code change here: the catalog parser already prefersshortand falls back todescription.--jsonoutput on the catalog endpoint for richer agent consumption.Related
k6 x: Fetch and show subcommands #5907