Support dynamic resource command inputs#17249
Conversation
Add dynamic command input metadata to Hosting, the auxiliary backchannel, CLI JSON output, and VS Code resource command prompting. The CLI now exposes a hidden load-arguments path for tools to refresh dynamic input metadata and improves validation errors for dynamically disabled arguments. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
🚀 Dogfood this PR with:
curl -fsSL https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.sh | bash -s -- 17249Or
iex "& { $(irm https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.ps1) } 17249" |
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR adds end-to-end support for dynamic resource command inputs (disabled/required/options/defaults that change based on earlier answers) by flowing dynamic-loading metadata from Hosting → auxiliary backchannel → CLI JSON, and by adding a VS Code prompt path that can re-query the AppHost for refreshed argument metadata.
Changes:
- Extend Hosting/backchannel contracts to carry dynamic-loading metadata and (optionally) return post-load argument inputs for validation-only requests.
- Update CLI resource command parsing/validation to defer dynamic argument validation to Hosting, plus add a hidden
--load-argumentsmode that returns loaded argument inputs as JSON. - Update VS Code prompting to reload dynamic inputs during the argument-collection flow, including initial loads to surface initially-disabled dependent inputs.
Show a summary per file
| File | Description |
|---|---|
| tests/Aspire.Hosting.Tests/ResourceCommandServiceTests.cs | Adds tests ensuring dynamic-disabled arguments aren’t rejected during argument creation and that disabled-after-load yields validation errors. |
| tests/Aspire.Hosting.Tests/Backchannel/AuxiliaryBackchannelRpcTargetTests.cs | Adds coverage for returning loaded argument inputs and allowing arguments enabled by dynamic loading. |
| tests/Aspire.Cli.Tests/Commands/ResourceCommandTests.cs | Adds CLI tests for --load-arguments JSON output and for deferring dynamic validation to Hosting during execution. |
| tests/Aspire.Cli.Tests/Commands/ResourceCommandHelperTests.cs | Updates tests for new validation-focused CLI error messaging. |
| tests/Aspire.Cli.Tests/Backchannel/ResourceSnapshotMapperTests.cs | Verifies dynamic-loading metadata is mapped into CLI JSON. |
| src/Shared/Model/Serialization/ResourceJson.cs | Adds JSON contract for dynamic-loading metadata on command arguments. |
| src/Aspire.Hosting/Backchannel/BackchannelDataTypes.cs | Extends backchannel request/options/response and snapshot argument types to support returning loaded inputs and dynamic-loading metadata. |
| src/Aspire.Hosting/Backchannel/AuxiliaryBackchannelRpcTarget.cs | Implements ReturnArgumentInputs behavior for validation-only requests and factors argument mapping into a helper. |
| src/Aspire.Hosting/ApplicationModel/ResourceCommandService.cs | Defers rejection of dynamically-disabled inputs until after dynamic loading and adds disabled-with-value validation. |
| src/Aspire.Cli/Commands/ResourceCommandHelper.cs | Improves CLI messaging by distinguishing argument-validation failures from execution failures. |
| src/Aspire.Cli/Commands/ResourceCommand.cs | Adds hidden --load-arguments execution path and relaxes CLI-side validation for dynamic inputs / load-arguments mode. |
| src/Aspire.Cli/Backchannel/ResourceSnapshotMapper.cs | Maps dynamic-loading metadata into the CLI JSON model for consumers (VS Code). |
| src/Aspire.Cli/Backchannel/BackchannelJsonSerializerContext.cs | Adds ResourceSnapshotCommandArgument[] to the CLI backchannel JSON source-gen context. |
| src/Aspire.Cli/Backchannel/AppHostAuxiliaryBackchannel.cs | Forwards the ReturnArgumentInputs option to Hosting. |
| extension/src/views/ResourceCommandArguments.ts | Adds dynamic-reload prompting flow, loader abstraction, and returns { args, containsSecret } instead of a raw argv array. |
| extension/src/views/AspireAppHostTreeProvider.ts | Wires dynamic loading via aspire resource ... --load-arguments and blocks prompting if load fails. |
| extension/src/views/AppHostDataRepository.ts | Extends the extension-side JSON contract to include dynamicLoading. |
| extension/src/test/resourceCommandArguments.test.ts | Adds unit coverage for dynamic argument detection and loader/blocking behavior. |
| extension/src/loc/strings.ts | Adds localized strings for dynamic input unsupported/failed/loading states. |
| extension/src/extension.ts | Updates CodeLens resource action handling to use the new { args, containsSecret } result shape. |
| extension/package.nls.json | Adds string resources for dynamic-input prompting states. |
| extension/loc/xlf/aspire-vscode.xlf | Adds corresponding XLF entries for new localized strings. |
Copilot's findings
- Files reviewed: 22/22 changed files
- Comments generated: 1
Share the resource command argument loader between the tree view and CodeLens resource-action flow so dynamic command inputs can be loaded with the AppHost path from CodeLens. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
mitchdenny
left a comment
There was a problem hiding this comment.
Few minor issues. but approving. Also filed an issue for a potential quality of life improvement for folks in the next release (non blocking).
mitchdenny
left a comment
There was a problem hiding this comment.
Review of dynamic resource command inputs. 3 inline findings below.
Additional minor (no inline anchor — function is on an unchanged line): hasSecretResourceCommandArguments in extension/src/views/ResourceCommandArguments.ts is no longer called from extension.ts or AspireAppHostTreeProvider.ts after this PR — the new CollectedResourceCommandArguments.containsSecret (computed against the final, post-dynamic-load values) replaces it. The function is still exported and is now only referenced by tests. Worth deleting (with its test) if no production code consumes it; otherwise it's an attractive nuisance because it computes the answer from the stale snapshot and would give wrong results for dynamic inputs.
Harden VS Code dynamic input prompting against changing input sets, require an AppHost path for dynamic metadata loading, remove stale secret detection, and add a fallback diagnostic when loaded argument metadata is missing. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Addressed the additional review note from review 4352954787. |
Only report submitted values for disabled dynamic inputs when their load callback did not run because dependencies were incomplete. This preserves Browser Logs default profile values while keeping stale dependent submissions actionable. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Cover the case where a dynamic input loads, remains disabled, and carries a default value so it does not report a disabled-argument validation error. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Re-running the failed jobs in the CI workflow for this pull request because 1 job was identified as retry-safe transient failures in the CI run attempt.
|
Make the VS Code dynamic argument loader parse the entire hidden CLI stdout as a single JSON payload and fail if any extra text is emitted, surfacing CLI output bugs instead of ignoring them. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Yea I gotta admit that is a terrible experience. I think the only way to fix it is to not use the terminal here. I'll see what can be done. |
Rename the dynamic argument loader dependency to emphasize extension-host CLI execution instead of visible terminal usage, and document that only final resource command invocation uses the VS Code terminal. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Display a busy QuickInput while dynamic resource command inputs reload between prompts, and use the clearer text 'Updating command inputs...' for the transient state. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
❌ CLI E2E Tests failed — 95 passed, 1 failed, 5 unknown (commit Failed Tests
View all recordings
📹 Recordings uploaded automatically from CI run #26418223128 |
|
✅ No documentation update needed. The documentation changes were written and committed locally to branch Signals triggered (4): Prepared documentation change: A new |


Description
Resource commands can define dynamic inputs whose enabled state, defaults, or choice options depend on earlier answers. This change carries that metadata from Hosting through the auxiliary backchannel and CLI JSON so tool clients can prompt correctly instead of blocking or relying on stale command snapshots.
The implementation keeps dynamic input loading authoritative in the AppHost. VS Code uses a hidden
aspire resource ... --load-argumentspath to send the current partial prompt state, Hosting runs the dynamic load callbacks withValidateOnly, and the refreshed argument metadata is returned as JSON. Regular CLI execution still works with supplied arguments, while dynamic required/disabled/choice validation is deferred until after Hosting has loaded the current metadata.User-facing usage
VS Code resource command prompts now refresh dynamic inputs as earlier values are selected, including initially-disabled dependent inputs. If dynamic input loading fails, VS Code blocks the command and tells the user to run it from the Dashboard or CLI instead of prompting with stale metadata.
CLI execution works with supplied dynamic arguments:
Invalid dynamic state is reported as validation instead of execution failure:
Validation:
dotnet test --project tests/Aspire.Cli.Tests/Aspire.Cli.Tests.csproj --no-launch-profile -- --filter-class "*.ResourceCommandTests" --filter-not-trait "quarantined=true" --filter-not-trait "outerloop=true"dotnet test --project tests/Aspire.Cli.Tests/Aspire.Cli.Tests.csproj --no-launch-profile -- --filter-method "*.ExecuteGenericCommandAsync_WithValidationErrors_DisplaysArgumentErrors" --filter-method "*.ResourceCommand_DisplaysValidationErrorArgumentNamesAsCliOptions" --filter-not-trait "quarantined=true" --filter-not-trait "outerloop=true"dotnet test --project tests/Aspire.Hosting.Tests/Aspire.Hosting.Tests.csproj --no-launch-profile -- --filter-method "*.ExecuteCommandAsync_SubmittedDynamicArgumentStillDisabledAfterLoading_ReturnsDisabledValidationError" --filter-method "*.ExecuteCommandAsync_LoadsDependentChoiceOptionsBeforeBuiltInValidation" --filter-not-trait "quarantined=true" --filter-not-trait "outerloop=true"npm run compile-tests,npm run compile -- --mode development,npm run lint -- --quietfromextension/npm run unit-test -- --grep ResourceCommandArgumentsfromextension/argument-commands dependent-argumentsFixes # (issue)
Checklist
<remarks />and<code />elements on your triple slash comments?