Repository navigation
docs: correct custom resource command CLI arguments to named options - #1467
Conversation
Custom resource command arguments are exposed by the CLI as named `--<name>` options (with kebab-case aliases), not ordered positional values. Update the "Command arguments" intro, the InteractionInput InputType CLI behavior column, and the "Pass arguments from the CLI" section to match ResourceCommand.cs behavior, including the required-option error message. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Updates the custom resource commands documentation to reflect the Aspire CLI’s actual behavior: command “arguments” declared via CommandOptions.Arguments are passed as named --<name> options (with kebab-case aliases), not positional tokens.
Changes:
- Corrected the “Command arguments” introduction and
InteractionInputproperties lead-in to describe named CLI options. - Updated the
InputTypetable “CLI behavior” column to show the correct option forms (including boolean flags). - Rewrote the “Pass arguments from the CLI” section to use
--text ... --repeat ..., clarify ordering, document kebab-case aliases, and show the missing-required-option error.
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Frontend HTML artifact readyThe latest frontend build uploaded the This comment updates automatically when a new frontend build artifact is uploaded. |
Adam Ratzman (adamint)
left a comment
There was a problem hiding this comment.
A few behavior details in the updated CLI guidance are still inaccurate. Details inline.
David Pine (IEvangelist)
left a comment
There was a problem hiding this comment.
Docs-accuracy review — verdict: COMMENT ✅ (accurate; two wording nuances)
Phase A source of truth: microsoft/aspire @ release/13.5 (SHA 1d922813c0f9bc14f7d817c817a8ab46b288bb44), file src/Aspire.Cli/Commands/ResourceCommand.cs.
Claims extracted: 14 non-narrative → 12 verified, 2 verified‑with‑nuance, 0 contradicted, 0 unverifiable.
Phase B (doc-tester, blind): exercised /fundamentals/custom-resource-commands/ (intro, InteractionInput properties / InputType table, Pass arguments from the CLI). 0 critical, 1 minor styling note. Page renders correctly and no stale "positional" wording remains.
The core correction is right: custom resource command arguments are exposed by the CLI as named --<name> options, not ordered positional tokens. ResourceCommand.CreateCommandArgumentOption builds a System.CommandLine Option per argument (new Option<...>($"--{optionName}")) and the parser explicitly forwards leftover tokens as unknown names rather than binding them positionally (ResourceCommand.cs:349-355: "Metadata-backed command inputs are options only… instead of binding it positionally."). Boolean → flag, Number → Option<double?>, Choice/Text/SecretText → validated string option, and the Required option '--<name>' was not provided. message all match the source exactly.
Phase A — Claim verification
Nuances worth considering (both verified-with-nuance, non-blocking)
1. Which spelling is the option's canonical name vs. the alias is inverted.
"Each option name matches the input's
Name, and a kebab-case alias is also accepted for multi-word names. For example, an input namedLogLevelaccepts both--LogLeveland--log-level."
The user-facing takeaway is correct — both --LogLevel and --log-level are accepted. But the direction is reversed relative to the source: the kebab-case form is the canonical option name and the exact Name is added as the alias, not the other way around:
ResourceCommand.cs:387—var optionName = ToKebabCase(argument.Name);→ the option is created as--{optionName}(kebab).ResourceCommand.cs:444-448—var exactName = $"--{argument.Name}"; if (exactName != "--{optionName}") option.Aliases.Add(exactName);→ the exactNameis the added alias.ResourceCommand.cs:855-858and:888—--help/usage renders the kebab-case name as the canonical option label.
So for LogLevel, --help shows --log-level (canonical) and --LogLevel works as an alias. Consider rewording to something like: "Each argument is exposed as an option whose canonical name is the kebab-case form of the input's Name (e.g. --log-level); the exact Name (--LogLevel) is also accepted as an alias." For single-word names (text, repeat, url) exact == kebab, so the current example command is unaffected.
2. "the AppHost performs … built-in validation" is slightly under-stated for the CLI.
"The CLI passes all option values as strings; the AppHost performs type coercion and built-in validation before invoking the command callback."
Values are indeed forwarded as strings (ResourceCommand.cs:334-346 stringifies bool/number/string into the arguments payload). But the CLI itself also performs some built-in validation before anything reaches the AppHost — required-option presence (:294-308), choice membership (:421-431), and numeric parsing via Option<double?> (:398). The very next sentence in this PR (required-option error emitted by the CLI) is consistent with that, so this is only a small simplification. Optional: "…the AppHost performs the remaining type coercion and validation…" or note that basic required/choice/number checks happen CLI-side.
Verified claims (12) with evidence — microsoft/aspire @ release/13.5, src/Aspire.Cli/Commands/ResourceCommand.cs
| # | Claim | Verdict | Evidence |
|---|---|---|---|
| 1 | "Command arguments" intro: CLI accepts args as named --<name> options |
verified | :287-292, :394/398/404, :349-355 |
| 2 | InteractionInput properties intro: each input → "one named --<name> option for the CLI" |
verified | :287-292, :404 |
| 3 | Text → --<name> <value> string option |
verified | :404 (Option<string?>) |
| 4 | Number → --<name> <value> parsed as number |
verified | :398 (Option<double?>) |
| 5 | Boolean → --<name> flag (true when present) |
verified | :394-397 (Option<bool>), :412-416 (ArgumentArity.ZeroOrOne), :334-336, help shows no value placeholder :856-858 |
| 6 | Choice → --<name> <value> matching one of Options |
verified | :404 + choice validator :421-431 |
| 7 | SecretText → --<name> <value> string option |
verified | :404 (non-bool/number → string) |
| 8 | CLI section intro: named options, "each declared argument is exposed as its own option, so the order … doesn't matter" | verified | :287-292 (one option per arg; named parsing is order-independent) |
| 9 | Example aspire resource myservice send-message --text "Hello world" --repeat 3 --apphost MyApp.AppHost.csproj |
verified | --text/--repeat = --{ToKebabCase(name)} (:387,:404); --apphost is a real option (:43) |
| 10 | "--text sets the text argument and --repeat sets the repeat argument" |
verified | :404, :343-345 |
| 11 | Required-missing → CLI reports Required option '--<name>' was not provided. |
verified | :301-303 (exact string), name built at :298 (a plural variant exists at :305-307, not documented — fine) |
| 12 | "Any value that fails validation returns a structured error the same way" | verified | :315-324 returns joined error message; validators :421-441 |
Phase B — Doc-tester results (blind, playwright against local pnpm dev build of this PR)
Route exercised: http://localhost:<dev>/fundamentals/custom-resource-commands/ — Command arguments, InteractionInput properties + InputType table, and Pass arguments from the CLI.
🔴 Critical issues: none.
🟡 Warnings (1, minor / not introduced by this PR):
- The inline
`--<name>`(and`--text`,`--log-level`…) code chips visually render the leading--as a single long dash because the site's monospace font (Fira Code) ligates double hyphens (font-variant-ligatures: normal, socaltstays on). The underlying DOM text and copy value are correct — two U+002D hyphens (confirmed:hasEmDash: false,doubleHyphen: true). This is site-wide styling, not a defect in this change, but this PR adds many inline--chips so the ligature is more visible here. A reader who only skims the prose might misread--as an em-dash, though the fencedTerminalexample disambiguates it. Purely cosmetic; flagging for awareness, not as a change request.
✅ Passed checks:
- Page returns HTTP 200 and renders cleanly (tabs, tables, code blocks,
<Aside>note all intact). - "Command arguments" and InteractionInput properties intros both render with the new named‑option wording.
InputTypetable renders all five rows/columns correctly — the literal<name>/<value>angle brackets inside backticks did not break the markdown table or get parsed as JSX/MDX.- Pass arguments from the CLI: prose,
Terminalcode block, and the<Aside type="note">all render; the example command and the follow-up explanation are internally consistent (--text/--repeatin the example match the prose). - Consistency: the page contains zero remaining "positional" / "ordered positional" / "by position" / "maps to the first argument" text — no stale contradictions left behind by the edit.
Knowledge gaps: none blocking. The LogLevel example is a helpful touch for explaining multi-word naming; a new user can follow the section end-to-end.
Console note: 7 console errors were observed, all Vite dev-server artifacts (504 Outdated Optimize Dep for the Astro dev toolbar modules: astro, xray, audit, settings, toolbar, ui-library). These are dev-only and unrelated to the documentation content.
Automated docs-accuracy review (doc-pr-reviewer). Phase A verified prose against microsoft/aspire source; Phase B validated the rendered page blind to source. No contradictions and no critical rendering issues found — only the two optional wording nuances above.
- Boolean CLI behavior: document the optional explicit value (`--<name>` sets `true`, or `--<name> <value>`) instead of a presence-only flag. - Attribute Number/Boolean parsing and built-in validation to the CLI, which forwards string values to the AppHost (not the other way around). - Note that argument option names that collide with an Aspire CLI option (for example `--log-level` or `--apphost`) must be passed after a `--` delimiter to reach the command. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Stale
8bd3837
into
release/13.5
Fixes #1463.
The
fundamentals/custom-resource-commandspage described custom resource command CLI arguments as ordered positional values, but the CLI actually exposes each declared input as a named--<name>option. The documented example (send-message "Hello world" 3) fails in practice because those tokens are treated as unknown, not bound positionally.Changes
InteractionInputproperties lead-in now say the CLI accepts named--<name>options.InputTypetable (CLI behavior column) — replaced "Positional string value" / "Positional string parsed as number" with the actual option forms (--<name> <value>, and--<name>flag for booleans).--text "Hello world" --repeat 3, notes that argument order doesn't matter, documents the kebab-case aliases (e.g. an input namedLogLevelaccepts both--LogLeveland--log-level), and shows theRequired option '--<name>' was not provided.error.Source of truth
Verified against
ResourceCommand.csonrelease/13.5:new Option<...>($"--{optionName}"), whereoptionNameis the kebab-casedName, with the exactNameadded as an alias.Required option '--<name>' was not provided..All angle brackets in the new copy stay inside inline-code spans / code fences, so MDX doesn't parse them as JSX (matching the existing
IReadOnlyList<...>table cell).Targets
release/13.5as requested in the issue.