Skip to content

Thread PromptBindings through AgentInitCommand and NewCommand#18192

Open
JamesNK wants to merge 2 commits into
mainfrom
jamesnk/agent-init-prompt-bindings
Open

Thread PromptBindings through AgentInitCommand and NewCommand#18192
JamesNK wants to merge 2 commits into
mainfrom
jamesnk/agent-init-prompt-bindings

Conversation

@JamesNK

@JamesNK JamesNK commented Jun 13, 2026

Copy link
Copy Markdown
Member

Summary

Thread PromptBinding<string?> parameters for --skill-locations and --skills through AgentInitCommand.PromptAndChainAsync and ExecuteAgentInitAsync so all prompts are controllable via CLI options in non-interactive mode.

Changes

  • Add PromptBinding<string?> params for --skill-locations and --skills to PromptAndChainAsync and ExecuteAgentInitAsync so all prompts are controllable via CLI options in non-interactive mode.
  • Register --skill-locations and --skills options on InitCommand and NewCommand with Recursive = true so they propagate to subcommands.
  • Remove ParseResult parameter from ExecuteAgentInitAsync since bindings already capture whether an option was explicitly provided.
  • Make all PromptBinding params non-nullable (required) and remove default values from CancellationToken and selectByDefault parameters.
  • Simplify ShouldSkipBundleCatalogResolution to resolve from binding instead of branching on ParseResult presence.
  • Move CancellationToken to last parameter position consistently.
  • Add integration tests for non-interactive --skill-locations/--skills on AgentInitCommand, InitCommand, and NewCommand.

Testing

All 4099 CLI tests pass locally (4073 succeeded, 26 skipped).

- Add PromptBinding<string?> params for --skill-locations and --skills
  to PromptAndChainAsync and ExecuteAgentInitAsync so all prompts are
  controllable via CLI options in non-interactive mode.
- Register --skill-locations and --skills options on InitCommand and
  NewCommand with Recursive=true so they propagate to subcommands.
- Remove ParseResult parameter from ExecuteAgentInitAsync since bindings
  already capture whether an option was explicitly provided.
- Make all PromptBinding params non-nullable (required) and remove
  default values from CancellationToken and selectByDefault parameters.
- Simplify ShouldSkipBundleCatalogResolution to resolve from binding
  instead of branching on ParseResult presence.
- Add integration tests for non-interactive --skill-locations/--skills
  on AgentInitCommand, InitCommand, and NewCommand.
- Move CancellationToken to last parameter position consistently.
Copilot AI review requested due to automatic review settings June 13, 2026 04:29
@github-actions

github-actions Bot commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

🚀 Dogfood this PR with:

⚠️ WARNING: Do not do this without first carefully reviewing the code of this PR to satisfy yourself it is safe.

curl -fsSL https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.sh | bash -s -- 18192

Or

  • Run remotely in PowerShell:
iex "& { $(irm https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.ps1) } 18192"

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

This PR threads PromptBinding<string?> parameters for --skill-locations and --skills through AgentInitCommand.PromptAndChainAsync and ExecuteAgentInitAsync, making all prompts controllable via CLI options in non-interactive mode. It also simplifies ShouldSkipBundleCatalogResolution by removing the ParseResult-based branching in favor of unified binding resolution.

Changes:

  • Add --skill-locations and --skills options to InitCommand and NewCommand (sharing the option instances defined in AgentInitCommand with Recursive = true), and convert PromptAndChainAsync/ExecuteAgentInitAsync to accept explicit non-nullable PromptBinding<string?> parameters.
  • Reorder parameters to place CancellationToken last consistently, including in the INewCommandPrompter.PromptForOutputPath interface and all its implementations.
  • Add integration tests verifying --skill-locations none prevents skill installation and --skill-locations standard --skills <name> installs only the specified skill.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/Aspire.Cli/Commands/AgentInitCommand.cs Make s_skillLocationsOption internal, add Recursive = true to both options, refactor PromptAndChainAsync/ExecuteAgentInitAsync/ShouldSkipBundleCatalogResolution signatures to use explicit bindings
src/Aspire.Cli/Commands/InitCommand.cs Register --skill-locations option, create binding, update call to PromptAndChainAsync
src/Aspire.Cli/Commands/NewCommand.cs Register both options, create bindings, update call to PromptAndChainAsync, reorder INewCommandPrompter.PromptForOutputPath params
src/Aspire.Cli/Templating/DotNetTemplateFactory.cs Update call site for reordered PromptForOutputPath
src/Aspire.Cli/Templating/CliTemplateFactory.cs Update call site for reordered PromptForOutputPath
tests/Aspire.Cli.Tests/Commands/AgentInitCommandTests.cs Add new parameters to existing PromptAndChainAsync tests, add 2 new tests for --skill-locations/--skills
tests/Aspire.Cli.Tests/Commands/InitCommandTests.cs Add 2 new integration tests for --skill-locations/--skills
tests/Aspire.Cli.Tests/Commands/NewCommandTests.cs Add 2 new integration tests for --skill-locations/--skills
tests/Aspire.Cli.Tests/TestServices/TestNewCommandPrompter.cs Update PromptForOutputPath signature
tests/Aspire.Cli.Tests/Templating/DotNetTemplateFactoryTests.cs Update PromptForOutputPath signature

Comment thread src/Aspire.Cli/Commands/AgentInitCommand.cs
@JamesNK

JamesNK commented Jun 13, 2026

Copy link
Copy Markdown
Member Author

PR Testing Report

PR Information

Artifact Version Verification

  • Expected Commit: 818cf44
  • Installed Version: 13.5.0-dev (locally-built from PR head commit — CI artifacts not yet available)
  • Status: ✅ Verified (local commit matches PR head)

Changes Analyzed

Files Changed

  • src/Aspire.Cli/Commands/AgentInitCommand.cs - Modified (core refactoring)
  • src/Aspire.Cli/Commands/InitCommand.cs - Modified (register options, pass bindings)
  • src/Aspire.Cli/Commands/NewCommand.cs - Modified (register options, pass bindings)
  • src/Aspire.Cli/Templating/CliTemplateFactory.cs - Modified (CancellationToken ordering)
  • src/Aspire.Cli/Templating/DotNetTemplateFactory.cs - Modified (CancellationToken ordering)
  • tests/Aspire.Cli.Tests/Commands/AgentInitCommandTests.cs - Modified (new integration tests)
  • tests/Aspire.Cli.Tests/Commands/InitCommandTests.cs - Modified (new integration tests)
  • tests/Aspire.Cli.Tests/Commands/NewCommandTests.cs - Modified (new integration tests)
  • tests/Aspire.Cli.Tests/Templating/DotNetTemplateFactoryTests.cs - Modified (interface update)
  • tests/Aspire.Cli.Tests/TestServices/TestNewCommandPrompter.cs - Modified (interface update)

Change Categories

  • CLI changes detected
  • Hosting integration changes
  • Dashboard changes
  • Template changes
  • Client/Component changes
  • VS Code extension changes
  • Test changes

Test Scenarios Executed

Scenario 1: CLI Version Verification

Objective: Verify locally-built CLI matches PR head commit
Coverage Type: Setup verification
Status: ✅ Passed

Evidence:

  • Local git HEAD: 818cf44
  • CLI version: 13.5.0-dev
  • CI artifacts not yet built (PR just created)

Scenario 2: aspire agent init --skill-locations none

Objective: Verify no skills are installed when --skill-locations none is passed
Coverage Type: Happy path
Status: ✅ Passed

Steps:

  1. Created empty workspace directory
  2. Ran aspire agent init --workspace-root <dir> --skill-locations none
  3. Verified no skill directories were created

Evidence:

  • Output: ✅ Agent environment configuration complete.
  • No .agents/skills directory created
  • Exit code: 0

Scenario 3: aspire agent init --skill-locations standard --skills aspire

Objective: Verify only the specified skill is installed at the specified location
Coverage Type: Happy path
Status: ✅ Passed

Steps:

  1. Created empty workspace directory
  2. Ran aspire agent init --workspace-root <dir> --skill-locations standard --skills aspire
  3. Verified only aspire skill files exist

Evidence:

  • Output: 🤖 Installed Aspire agent skills: Skills: aspire, Locations: .agents/skills
  • Only .agents/skills/aspire/SKILL.md created (plus reference files)
  • Exit code: 0

Scenario 4: aspire new with --skill-locations none (non-interactive)

Objective: Verify --skill-locations propagates to template subcommands via Recursive=true
Coverage Type: Happy path
Status: ✅ Passed

Steps:

  1. Ran aspire new aspire-starter --non-interactive --skill-locations none
  2. Agent init chained but installed no skills

Evidence:

  • Output shows 🤖 Detecting agent environments... and ✅ Agent environment configuration complete.
  • No skills directories in the project
  • Exit code: 0

Scenario 5: aspire agent init in existing Aspire project with specific skills

Objective: Verify agent init works correctly in an existing project with --skills aspire
Coverage Type: Happy path
Status: ✅ Passed

Steps:

  1. Created new aspire-starter project (with --suppress-agent-init)
  2. Ran aspire agent init --workspace-root <dir> --non-interactive --skill-locations standard --skills aspire
  3. Verified only aspire skill installed

Evidence:

  • Output: 🤖 Installed Aspire agent skills: Skills: aspire, Locations: .agents/skills
  • .agents/skills/aspire/SKILL.md present
  • Exit code: 0

Scenario 6: Invalid --skill-locations value

Objective: Verify clear validation error for unrecognized location
Coverage Type: Unhappy path
Status: ✅ Passed

Steps:

  1. Ran aspire agent init --skill-locations "invalid-location"

Expected Outcome: Clear validation error listing available values
Actual Outcome: The value 'invalid-location' is not valid for '--skill-locations'. Available values: Standard, Claude Code, VS Code / GitHub Copilot, OpenCode

  • Exit code: 21 (InvalidCommand)

Scenario 7: Invalid --skills value

Objective: Verify clear validation error for unrecognized skill name
Coverage Type: Unhappy path
Status: ✅ Passed

Steps:

  1. Ran aspire agent init --skill-locations standard --skills "nonexistent-skill-xyz"

Expected Outcome: Clear validation error listing available skills
Actual Outcome: The value 'nonexistent-skill-xyz' is not valid for '--skills'. Available values: aspire, aspire-deployment, aspire-init, ...

  • Exit code: 21 (InvalidCommand)

Scenario 8: Unrecognized bundle skill name

Objective: Verify error for skill name that only a bundle could provide
Coverage Type: Unhappy path
Status: ✅ Passed

Steps:

  1. Ran aspire agent init --skill-locations standard --skills "fake-bundle-skill"

Expected Outcome: Validation error (same as above since the name isn't in the catalog)
Actual Outcome: Same clear error with available values listed

  • Exit code: 21 (InvalidCommand)

Unit Test Results

All 4099 CLI tests pass:

  • Succeeded: 4073
  • Skipped: 26 (pre-existing skips)
  • Failed: 0
  • Duration: ~67 seconds

Summary

Scenario Status Notes
CLI Version Verification ✅ Passed Local build matches PR head
agent init --skill-locations none ✅ Passed No skills installed
agent init --skill-locations standard --skills aspire ✅ Passed Only specified skill
aspire new --skill-locations none ✅ Passed Options propagate via Recursive
agent init in existing project ✅ Passed Works in real project
Invalid --skill-locations ✅ Passed Clear error, exit 21
Invalid --skills ✅ Passed Clear error, exit 21
Unrecognized bundle skill ✅ Passed Clear error, exit 21

Overall Result

✅ PR VERIFIED

Observations

  • All non-interactive --skill-locations and --skills options work correctly
  • Options propagate to aspire new template subcommands via Recursive = true
  • Invalid inputs produce clear, actionable validation errors with exit code 21
  • aspire init has a pre-existing limitation: the AppHost Language prompt is not yet PromptBinding-enabled for non-interactive mode (unrelated to this PR)
  • Full CLI test suite (4099 tests) passes with 0 failures

@JamesNK JamesNK marked this pull request as ready for review June 13, 2026 04:40
@github-actions

Copy link
Copy Markdown
Contributor

Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt.

@github-actions

Copy link
Copy Markdown
Contributor

CLI E2E Tests unknown — 115 passed, 0 failed, 2 unknown (commit 9045115)

View all recordings
- Test Detail
AddPackageInteractiveWhileAppHostRunningDetached Recording · Job · CLI logs
AddPackageWhileAppHostRunningDetached Recording · Job · CLI logs
AgentCommands_AllHelpOutputs_AreCorrect Recording · Job · CLI logs
AgentInitCommand_DefaultSelection_InstallsDefaultSkills Recording · Job · CLI logs
AgentInitCommand_MigratesDeprecatedConfig Recording · Job · CLI logs
AgentInit_NonInteractive_BundleOnlySkillsNotInCatalog Recording · Job · CLI logs
AgentMcpListResources_ExcludesResourceMarkedWithExcludeFromMcp Recording · Job · CLI logs
AgentMcpListStructuredLogsReturnsLogsFromStarterApp Recording · Job · CLI logs
AgentMcpListStructuredLogsReturnsLogsFromStarterApp_DevLocalhost Recording · Job · CLI logs
AgentMcpListStructuredLogsReturnsLogsFromStarterApp_Isolated Recording · Job · CLI logs
AllPublishMethodsBuildDockerImages Recording · Job · CLI logs
AspireAddAndStartWorkAgainstLegacyAppHostTs Recording · Job · CLI logs
AspireAddPackageVersionToDirectoryPackagesProps Recording · Job · CLI logs
AspireInitSingleFileAppHostRunsViaDotnetRunAppHost Recording · Job · CLI logs
AspireInit_ExistingAppHostDir_RecreatesNuGetConfigKeepsFiles Recording · Job · CLI logs
AspireInit_SolutionFile_BuildsAgainstChannelHive Recording · Job · CLI logs
AspireStartUpdatesStaleTypeScriptAppHostPath Recording · Job · CLI logs
AspireUpdateRemovesAppHostPackageVersionFromDirectoryPackagesProps Recording · Job · CLI logs
AspireUpdateRemovesOrphanAppHostPackageVersionWhenSdkAlreadyCurrent Recording · Job · CLI logs
Banner_DisplayedOnFirstRun Recording · Job · CLI logs
Banner_DisplayedWithExplicitFlag Recording · Job · CLI logs
Banner_NotDisplayedWithNoLogoFlag Recording · Job · CLI logs
CertificatesClean_RemovesCertificates Recording · Job · CLI logs
CertificatesTrust_WithNoCert_CreatesAndTrustsCertificate Recording · Job · CLI logs
CertificatesTrust_WithUntrustedCert_TrustsCertificate Recording · Job · CLI logs
ConfigSetGet_CreatesNestedJsonFormat Recording · Job · CLI logs
CreateAndRunAspireStarterProject Recording · Job · CLI logs
CreateAndRunAspireStarterProjectWithBundle Recording · Job · CLI logs
CreateAndRunEmptyAppHostProject Recording · Job · CLI logs
CreateAndRunJavaEmptyAppHostProject Recording · Job · CLI logs
CreateAndRunJsReactProject Recording · Job · CLI logs
CreateAndRunPolyglotAppHostWithDevLocalhostUrls Recording · Job · CLI logs
CreateAndRunPythonReactProject Recording · Job · CLI logs
CreateAndRunTypeScriptEmptyAppHostProject Recording · Job · CLI logs
CreateAndRunTypeScriptStarterProject Recording · Job · CLI logs
CreateJavaAppHostWithViteApp Recording · Job · CLI logs
CreateTypeScriptAppHostWithViteApp_UsesConfiguredToolchain Recording · Job · CLI logs
DashboardRunWithAgentMcpListTracesReturnsNoTraces Recording · Job · CLI logs
DashboardRunWithAgentMcpListTracesReturnsNoTraces_DevLocalhost Recording · Job · CLI logs
DashboardRunWithOtelTracesReturnsNoTraces Recording · Job · CLI logs
DashboardRunWithOtelTracesReturnsNoTraces_DevLocalhost Recording · Job · CLI logs
DeployK8sBasicApiService Recording · Job · CLI logs
DeployK8sWithExternalHelmChart Recording · Job · CLI logs
DeployK8sWithGarnet Recording · Job · CLI logs
DeployK8sWithMongoDB Recording · Job · CLI logs
DeployK8sWithMySql Recording · Job · CLI logs
DeployK8sWithPostgres Recording · Job · CLI logs
DeployK8sWithRabbitMQ Recording · Job · CLI logs
DeployK8sWithRedis Recording · Job · CLI logs
DeployK8sWithSqlServer Recording · Job · CLI logs
DeployK8sWithValkey Recording · Job · CLI logs
DeployTypeScriptAppToKubernetes Recording · Job · CLI logs
DescribeCommandResolvesReplicaNames Recording · Job · CLI logs
DescribeCommandShowsRunningResources Recording · Job · CLI logs
DetachFormatJsonProducesValidJson Recording · Job · CLI logs
DetachFormatJsonProducesValidJsonWhenRestartingExistingInstance Recording · Job · CLI logs
DoPublishAndDeployListStepsWork Recording · Job · CLI logs
DocsCommand_RendersInteractiveMarkdownFromLocalSource Recording · Job · CLI logs
DoctorCommand_DetectsDeprecatedAgentConfig Recording · Job · CLI logs
DoctorCommand_TypeScriptAppHostReportsMissingConfiguredToolchain Recording · Job · CLI logs
DoctorCommand_WithSslCertDir_ShowsTrusted Recording · Job · CLI logs
DoctorCommand_WithoutSslCertDir_ShowsPartiallyTrusted Recording · Job · CLI logs
DotNetRunFileBasedAppHostUsesAspireCliBundle Recording · Job · CLI logs
DotNetRunProjectAppHostUsesAspireCliBundle Recording · Job · CLI logs
GatewayWithoutExternalEndpoint_FailsPublishWithGuidance Recording · Job · CLI logs
GeneratedAspireDevScript_StartsWatchMode_WithConfiguredToolchain Recording · Job · CLI logs
GlobalMigration_HandlesCommentsAndTrailingCommas Recording · Job · CLI logs
GlobalMigration_HandlesMalformedLegacyJson Recording · Job · CLI logs
GlobalMigration_PreservesAllValueTypes Recording · Job · CLI logs
GlobalMigration_SkipsWhenNewConfigExists Recording · Job · CLI logs
GlobalSettings_MigratedFromLegacyFormat Recording · Job · CLI logs
IngressWithoutExternalEndpoint_FailsPublishWithGuidance Recording · Job · CLI logs
InitTypeScriptAppHost_AugmentsExistingViteRepoInWorkspaceSubdirectory Recording · Job · CLI logs
InteractiveCSharpInitCreatesExpectedFiles Recording · Job · CLI logs
InvalidAppHostPathWithComments_IsHealedOnRun Recording · Job · CLI logs
JavaScriptHostingApisRunFromTypeScriptAppHost Recording · Job · CLI logs
LatestCliCanStartStableChannelAppHost Recording · Job · CLI logs
LatestCliCanStartStableChannelTypeScriptAppHost Recording · Job · CLI logs
LegacySettingsMigration_AdjustsRelativeAppHostPath Recording · Job · CLI logs
LogsCommandShowsResourceLogs Recording · Job · CLI logs
OtelLogsReturnsStructuredLogsFromStarterApp Recording · Job · CLI logs
OtelLogsReturnsStructuredLogsFromStarterAppIsolated Recording · Job · CLI logs
ProcessCommandCallbackReceivesCliArguments Recording · Job · CLI logs
PsCommandListsRunningAppHost Recording · Job · CLI logs
PsFormatJsonOutputsOnlyJsonToStdout Recording · Job · CLI logs
PublishJavaScriptPatternsGeneratesExpectedDockerComposeArtifacts Recording · Job · CLI logs
PublishWithConfigureEnvFileUpdatesEnvOutput Recording · Job · CLI logs
PublishWithDockerComposeServiceCallbackSucceeds Recording · Job · CLI logs
PublishWithoutOutputPathUsesAppHostDirectoryDefault Recording · Job · CLI logs
ResourceCommand_FailedExec_ShowsLogPathAndLogHasEntries Recording · Job · CLI logs
ResourceCommand_SetAndDeleteParameterUpdatesDescribeOutput Recording · Job · CLI logs
RestoreGeneratesSdkFiles Recording · Job · CLI logs
RestoreGeneratesSdkFiles_WithConfiguredToolchain Recording · Job · CLI logs
RestoreRefreshesGeneratedSdkAfterAddingIntegration Recording · Job · CLI logs
RestoreSupportsConfigOnlyHelperPackageAndCrossPackageTypes Recording · Job · CLI logs
RunFromParentDirectory_UsesExistingConfigNearAppHost Recording · Job · CLI logs
RunReportsSyntaxErrorsForDotNetAppHost Recording · Job · CLI logs
RunReportsSyntaxErrorsForTypeScriptAppHost Recording · Job · CLI logs
SecretCrudOnDotNetAppHost Recording · Job · CLI logs
SecretCrudOnTypeScriptAppHost Recording · Job · CLI logs
StagingChannel_ConfigureAndVerifySettings_ThenSwitchChannels Recording · Job · CLI logs
StartAndWaitForTypeScriptSqlServerAppHostWithNativeAssets Recording · Job · CLI logs
StartReportsSyntaxErrorsForDotNetAppHost Recording · Job · CLI logs
StartReportsSyntaxErrorsForTypeScriptAppHost Recording · Job · CLI logs
StopAllAppHostsFromAppHostDirectory Recording · Job · CLI logs
StopJavaPolyglotAppHostUsingApphostDirectory Recording · Job · CLI logs
StopNonInteractiveSingleAppHost Recording · Job · CLI logs
StopTypeScriptPolyglotAppHostUsingApphostDirectory Recording · Job · CLI logs
StopWithNoRunningAppHostExitsSuccessfully Recording · Job · CLI logs
TerminalAttachFrontend_ShowsViteHelpAndDetaches Recording · Job · CLI logs
TypeScriptAppHostRunDoesNotDeadlockWhenLazyOptionsInvokeAsyncCallback Recording · Job · CLI logs
TypeScriptAppHostWithVite_AllowsDifferentGuestPkgManager Recording · Job · CLI logs
UnAwaitedChainsCompileWithAutoResolvePromises Recording · Job · CLI logs
UpdateToStable_CSharpEmptyAppHost_KeepsConfigChannel Recording · Job · CLI logs
UpdateToStable_CSharpSingleFileInit_KeepsConfigChannel Recording · Job · CLI logs
UpdateToStable_TypeScriptSingleFileInit_KeepsConfigChannel Recording · Job · CLI logs
UpdateToStable_TypeScript_PreviewsStablePkgsAndKeepsChannel Recording · Job · CLI logs

📹 Recordings uploaded automatically from CI run #27456840465

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants