Repository navigation
webcmd web fetch is invisible to --help, list, completions, and -h despite always being available #252
Description
What happens
webcmd web fetch always works — it is intercepted on the client-owned fast path in src/main.ts:79 before adapter discovery and before the hosted-mode branch, so it runs on a fresh install with zero plugins and in hosted mode. But nothing in the CLI's own surface says it exists.
On current main (0.5.4 build), with the web plugin not installed:
$ webcmd --help # no `web` under Commands or Site adapters
$ webcmd list # no web fetch
$ webcmd list -f json # 0 entries with "site": "web"
$ webcmd --get-completions webcmd web
# (empty)
$ webcmd web fetch --help
ArgumentError: --url must be an http or https URL
at clientOptions (…/dist/src/fetch/command.js:34:15)
hosted-contract.json has web/fetch-browser but no web/fetch entry either.
Meanwhile the command is fully functional:
$ webcmd web fetch --url https://example.com
# Example Domain
…
Why this happens
There are two registration paths for the same command and only one of them feeds discovery:
src/main.ts:79-82— the fast path. Hardcodedargv[0] === 'web' && argv[1] === 'fetch', hand-rolled argv parsing inclientOptions(). Always available. Never touches commander, so it contributes nothing to help,list,cli-manifest.json, or completions, and has no-h.plugins/web/fetch.js— a one-line side-effect import (import '@agentrhq/webcmd/fetch/command') that registerswebFetchCommandfromsrc/fetch/command.ts:5in the registry. This is what makes the command visible — but only for users who have installed thewebplugin.
So availability and discoverability are decoupled: the command works for everyone, and is listed only for the subset who installed a plugin they did not need in order to use it.
Why it matters
web fetch is the first call skills/smart-search/SKILL.md mandates, and the skill ships in the npm package (files includes skills/**). An agent that follows the documented practice of reading live command metadata before executing — webcmd list -f json, webcmd <site> <command> -h, exactly what smart-search instructs elsewhere — will conclude the command does not exist, or will try -h and get a stack trace telling it --url is required.
The --help output also advertises Run 'webcmd list' for full command details, which is inaccurate for this command.
Related but distinct: #247 is the mirror-image asymmetry (fetch-browser is listed in the hosted contract but not installed by default). #246 covers the stack-trace formatting on the fast path — this issue is that -h is not a supported argument at all, not that its failure prints badly.
Suggested fix
Register the web site in the built-in program so web fetch appears in --help, list, cli-manifest.json, and completions without a plugin install, and so webcmd web fetch -h prints real help.
Keep the src/main.ts fast path as-is. The comment above it is explicit that hosted mode must not read ~/.webcmd/clis or local site memory just to decide what commands exist, and the fast path is what guarantees web fetch stays client-owned in hosted mode. The two paths should stay separate; only the discovery side needs adding.
Two follow-ons if this lands:
- Decide whether
web/fetchbelongs inhosted-contract.json. It is client-owned, so it may warrant an explicit availability mode rather than a plain entry —npm run check:hosted-contractwill need to agree either way. - Once help is real,
clientOptions()and thecli({...})arg spec insrc/fetch/command.tsare two hand-maintained copies of the same flags (--url --timeout --max-chars --allow-private). Worth collapsing so help cannot drift from what the fast path actually parses.
Activity
refactor(fetch): move web into core and auto-escalate to the browser …
refactor(fetch): make web fetch a client-owned core command
beubax commentedon Aug 12, 2026
Closed by #295.
web fetchis now published through the core command surface/manifest, so help, list, completion, and structured command metadata can discover it without a plugin or adapter install.