Skip to content

docs: correct custom resource command CLI arguments to named options - #1467

Merged
David Pine (IEvangelist) merged 2 commits into
release/13.5from
dapine/fix-resource-command-cli-docs
Aug 13, 2026
Merged

David Pine (IEvangelist) merged 2 commits into
release/13.5from
dapine/fix-resource-command-cli-docs

Conversation

@IEvangelist

Copy link
Copy Markdown
Member

Fixes #1463.

The fundamentals/custom-resource-commands page 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

  • "Command arguments" intro and the InteractionInput properties lead-in now say the CLI accepts named --<name> options.
  • InputType table (CLI behavior column) — replaced "Positional string value" / "Positional string parsed as number" with the actual option forms (--<name> <value>, and --<name> flag for booleans).
  • "Pass arguments from the CLI" section — the example now uses --text "Hello world" --repeat 3, notes that argument order doesn't matter, documents the kebab-case aliases (e.g. an input named LogLevel accepts both --LogLevel and --log-level), and shows the Required option '--<name>' was not provided. error.

Source of truth

Verified against ResourceCommand.cs on release/13.5:

  • Each input becomes new Option<...>($"--{optionName}"), where optionName is the kebab-cased Name, with the exact Name added as an alias.
  • Missing required inputs produce Required option '--<name>' was not provided..
  • Leftover positional tokens are forwarded as unknown argument names, not bound positionally.

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.5 as requested in the issue.

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>
Copilot AI lite review requested due to automatic review settings August 11, 2026 19:02

Copilot AI 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.

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 InteractionInput properties lead-in to describe named CLI options.
  • Updated the InputType table “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.

@aspire-repo-bot

Copy link
Copy Markdown
Contributor

Frontend HTML artifact ready

The latest frontend build uploaded the frontend-dist artifact for PR #1467. Use the VS Code button below to open this PR with GitHub Artifacts Explorer and browse the built HTML locally.

VS Code: Open PR #1467 artifacts

This comment updates automatically when a new frontend build artifact is uploaded.

@adamint Adam Ratzman (adamint) left a comment

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.

A few behavior details in the updated CLI guidance are still inaccurate. Details inline.

Comment thread src/frontend/src/content/docs/fundamentals/custom-resource-commands.mdx Outdated
Comment thread src/frontend/src/content/docs/fundamentals/custom-resource-commands.mdx Outdated

@IEvangelist David Pine (IEvangelist) left a comment

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.

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 named LogLevel accepts both --LogLevel and --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 exact Name is the added alias.
  • ResourceCommand.cs:855-858 and :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, so calt stays 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 fenced Terminal example 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.
  • InputType table 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, Terminal code block, and the <Aside type="note"> all render; the example command and the follow-up explanation are internally consistent (--text/--repeat in 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>
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.

3 participants