Skip to content

Chain aspire agent init from aspire init on success#14629

Merged
mitchdenny merged 5 commits intorelease/13.2from
init-chain-agent-init
Mar 6, 2026
Merged

Chain aspire agent init from aspire init on success#14629
mitchdenny merged 5 commits intorelease/13.2from
init-chain-agent-init

Conversation

@mitchdenny
Copy link
Member

@mitchdenny mitchdenny commented Feb 23, 2026

Summary

After aspire init or aspire new completes successfully, prompt the user asking if they want to configure AI agent environments (aspire agent init). If they accept, chain into the agent init command.

Changes

  • src/Aspire.Cli/Commands/AgentInitCommand.cs: Added shared PromptAndChainAsync helper that handles the prompt-then-delegate pattern in one place
  • src/Aspire.Cli/Commands/InitCommand.cs: Inject AgentInitCommand and call PromptAndChainAsync on successful init
  • src/Aspire.Cli/Commands/NewCommand.cs: Same chaining pattern after successful aspire new
  • String resources: Added PromptRunAgentInit to resx, Designer.cs, and all xlf localization files
  • Unit tests: Updated two success-path tests to use nonInteractive: true to prevent the new prompt from hanging in non-interactive test environments
  • E2E tests: Added two new tests in AgentCommandTests.cs:
    • InitCommand_ChainsIntoAgentInit_WhenUserAccepts — verifies agent init starts after user accepts
    • InitCommand_SkipsAgentInit_WhenUserDeclines — verifies clean exit when user declines

Design Decisions

  • Shared PromptAndChainAsync on AgentInitCommand consolidates the prompt-then-delegate pattern (no duplication across commands)
  • Skips prompt in non-interactive mode (SupportsInteractiveInput check)
  • Default is true (opt-out) — pressing Enter accepts agent init to encourage adoption

Closes #14432

Copilot AI review requested due to automatic review settings February 23, 2026 22:35
@github-actions
Copy link
Contributor

github-actions bot commented Feb 23, 2026

🚀 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/dotnet/aspire/main/eng/scripts/get-aspire-cli-pr.sh | bash -s -- 14629

Or

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

Copy link
Contributor

Copilot AI left a comment

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 implements an optional prompt in aspire init that asks users if they want to configure AI agent environments by running aspire agent init after successful initialization. The chaining follows the established command delegation pattern used elsewhere in the CLI.

Changes:

  • Added post-init prompt to InitCommand that chains into AgentInitCommand when user accepts
  • Added localization string PromptRunAgentInit to all language files (marked as "new" for translation)
  • Updated unit tests to use non-interactive mode to prevent the new prompt from blocking tests
  • Added E2E tests to verify the chaining behavior when users accept or decline the prompt

Reviewed changes

Copilot reviewed 17 out of 18 changed files in this pull request and generated no comments.

Show a summary per file
File Description
src/Aspire.Cli/Commands/InitCommand.cs Injected AgentInitCommand dependency, added PromptAndRunAgentInitAsync helper method that conditionally prompts and chains to agent init
src/Aspire.Cli/Resources/InitCommandStrings.resx Added PromptRunAgentInit localization key
src/Aspire.Cli/Resources/InitCommandStrings.Designer.cs Auto-generated property for PromptRunAgentInit resource string
src/Aspire.Cli/Resources/xlf/*.xlf Added PromptRunAgentInit to all 13 localization files with state="new" for pending translation
tests/Aspire.Cli.Tests/Commands/InitCommandTests.cs Updated two test methods to set non-interactive mode to prevent the prompt from blocking tests
tests/Aspire.Cli.EndToEnd.Tests/AgentCommandTests.cs Added two E2E tests verifying the prompt and chaining behavior (accept/decline scenarios)
Files not reviewed (1)
  • src/Aspire.Cli/Resources/InitCommandStrings.Designer.cs: Language not supported

@mitchdenny
Copy link
Member Author

/deployment-test

@github-actions
Copy link
Contributor

🚀 Deployment tests starting on PR #14629...

This will deploy to real Azure infrastructure. Results will be posted here when complete.

View workflow run

@github-actions github-actions bot temporarily deployed to deployment-testing February 23, 2026 22:46 Inactive
@github-actions github-actions bot temporarily deployed to deployment-testing February 23, 2026 22:46 Inactive
@github-actions github-actions bot temporarily deployed to deployment-testing February 23, 2026 22:46 Inactive
@github-actions github-actions bot temporarily deployed to deployment-testing February 23, 2026 22:46 Inactive
@github-actions github-actions bot temporarily deployed to deployment-testing February 23, 2026 22:46 Inactive
@github-actions github-actions bot temporarily deployed to deployment-testing February 23, 2026 22:46 Inactive
@github-actions github-actions bot temporarily deployed to deployment-testing February 23, 2026 22:46 Inactive
@github-actions github-actions bot temporarily deployed to deployment-testing February 23, 2026 22:46 Inactive
@github-actions github-actions bot temporarily deployed to deployment-testing February 23, 2026 22:46 Inactive
@github-actions github-actions bot temporarily deployed to deployment-testing February 23, 2026 22:46 Inactive
@github-actions github-actions bot temporarily deployed to deployment-testing February 23, 2026 22:46 Inactive
@github-actions github-actions bot temporarily deployed to deployment-testing February 23, 2026 22:46 Inactive
@github-actions github-actions bot temporarily deployed to deployment-testing February 23, 2026 22:46 Inactive
@github-actions github-actions bot temporarily deployed to deployment-testing February 24, 2026 03:29 Inactive
@github-actions github-actions bot temporarily deployed to deployment-testing February 24, 2026 03:29 Inactive
@github-actions github-actions bot temporarily deployed to deployment-testing February 24, 2026 03:29 Inactive
@github-actions github-actions bot temporarily deployed to deployment-testing February 24, 2026 03:29 Inactive
@github-actions github-actions bot temporarily deployed to deployment-testing February 24, 2026 03:29 Inactive
@github-actions github-actions bot temporarily deployed to deployment-testing February 24, 2026 03:29 Inactive
@github-actions github-actions bot temporarily deployed to deployment-testing February 24, 2026 03:29 Inactive
@github-actions github-actions bot temporarily deployed to deployment-testing February 24, 2026 03:29 Inactive
@github-actions github-actions bot temporarily deployed to deployment-testing February 24, 2026 03:29 Inactive
@github-actions github-actions bot temporarily deployed to deployment-testing February 24, 2026 03:29 Inactive
@github-actions github-actions bot temporarily deployed to deployment-testing February 24, 2026 03:29 Inactive
@github-actions github-actions bot temporarily deployed to deployment-testing February 24, 2026 03:29 Inactive
@github-actions github-actions bot temporarily deployed to deployment-testing February 24, 2026 03:29 Inactive
@github-actions github-actions bot temporarily deployed to deployment-testing February 24, 2026 03:29 Inactive
@github-actions github-actions bot temporarily deployed to deployment-testing February 24, 2026 03:29 Inactive
@github-actions
Copy link
Contributor

Deployment E2E Tests failed

Summary: 23 passed, 1 failed, 0 cancelled

View workflow run

Passed Tests

  • ✅ AcaStarterDeploymentTests
  • ✅ AcaCompactNamingUpgradeDeploymentTests
  • ✅ AcaCompactNamingDeploymentTests
  • ✅ AksStarterWithRedisDeploymentTests
  • ✅ AzureAppConfigDeploymentTests
  • ✅ AcaCustomRegistryDeploymentTests
  • ✅ AzureLogAnalyticsDeploymentTests
  • ✅ AksStarterDeploymentTests
  • ✅ AzureKeyVaultDeploymentTests
  • ✅ AuthenticationTests
  • ✅ AzureServiceBusDeploymentTests
  • ✅ AzureContainerRegistryDeploymentTests
  • ✅ AzureStorageDeploymentTests
  • ✅ AppServicePythonDeploymentTests
  • ✅ AppServiceReactDeploymentTests
  • ✅ AcaExistingRegistryDeploymentTests
  • ✅ AzureEventHubsDeploymentTests
  • ✅ PythonFastApiDeploymentTests
  • ✅ VnetKeyVaultInfraDeploymentTests
  • ✅ VnetStorageBlobConnectivityDeploymentTests
  • ✅ VnetKeyVaultConnectivityDeploymentTests
  • ✅ VnetSqlServerInfraDeploymentTests
  • ✅ VnetStorageBlobInfraDeploymentTests

Failed Tests

  • ❌ AcaManagedRedisDeploymentTests

🎬 Terminal Recordings

Test Recording
DeployAzureAppConfigResourceCore ▶️ View Recording
DeployAzureContainerRegistryResourceCore ▶️ View Recording
DeployAzureEventHubsResourceCore ▶️ View Recording
DeployAzureKeyVaultResourceCore ▶️ View Recording
DeployAzureLogAnalyticsResourceCore ▶️ View Recording
DeployAzureServiceBusResourceCore ▶️ View Recording
DeployAzureStorageResourceCore ▶️ View Recording
DeployPythonFastApiTemplateToAzureAppServiceCore ▶️ View Recording
DeployPythonFastApiTemplateToAzureContainerAppsCore ▶️ View Recording
DeployReactTemplateToAzureAppServiceCore ▶️ View Recording
DeployStarterTemplateToAksCore ▶️ View Recording
DeployStarterTemplateToAzureContainerAppsCore ▶️ View Recording
DeployStarterTemplateWithCustomRegistryCore ▶️ View Recording
DeployStarterTemplateWithExistingRegistryCore ▶️ View Recording
DeployStarterTemplateWithKeyVaultPrivateEndpointCore ▶️ View Recording
DeployStarterTemplateWithRedisToAksCore ▶️ View Recording
DeployStarterTemplateWithStorageBlobPrivateEndpointCore ▶️ View Recording
DeployStarterWithManagedRedisToAzureContainerAppsCore ▶️ View Recording
DeployVnetKeyVaultInfrastructureCore ▶️ View Recording
DeployVnetSqlServerInfrastructureCore ▶️ View Recording
DeployVnetStorageBlobInfrastructureCore ▶️ View Recording
DeployWithCompactNamingFixesStorageCollisionCore ▶️ View Recording
UpgradeFromGaToDevDoesNotDuplicateStorageAccountsCore ▶️ View Recording

Copy link
Member

@JamesNK JamesNK left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good approach overall — clean refactoring of AgentInitCommand, proper interactive-mode guard, thorough E2E test updates, and nice shared DeclineAgentInitPrompt() helper.

Main concern: The defaultValue: true in both ConfirmAsync calls contradicts the PR description which says "Default is false (opt-in)". One of them needs to be corrected.

Missing E2E tests: The description mentions two new tests (InitCommand_ChainsIntoAgentInit_WhenUserAccepts and InitCommand_SkipsAgentInit_WhenUserDeclines) in AgentCommandTests.cs, but they don't appear in the diff.

Minor suggestions inline on code duplication and the unused parseResult parameter.


if (runAgentInit)
{
return await _agentInitCommand.ExecuteCommandAsync(parseResult, workspaceRoot, cancellationToken);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR description states "Default is false (opt-in) to avoid disrupting existing workflows", but the code uses defaultValue: true here and in NewCommand. With defaultValue: true, pressing Enter accepts agent init — the opposite of what the description claims.

Either the description or the code should be updated to match the intended behavior.

if (initResult != ExitCodeConstants.Success)
{
return initResult;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

InitCommand and NewCommand have nearly identical PromptAndRunAgentInitAsync methods (check success → check interactive → confirm → delegate). Consider extracting this into a shared helper on AgentInitCommand itself to keep the prompt-then-delegate pattern in one place:

internal async Task<int> PromptAndChainAsync(
    ICliHostEnvironment hostEnvironment,
    IInteractionService interactionService,
    string promptString,
    DirectoryInfo workspaceRoot,
    CancellationToken cancellationToken) { ... }

return ExecuteAgentInitAsync(workspaceRoot, cancellationToken);
}

protected override async Task<int> ExecuteAsync(ParseResult parseResult, CancellationToken cancellationToken)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since callers explicitly choose which overload to call, the "API consistency" rationale doesn't provide real value. A simpler internal method taking just (DirectoryInfo, CancellationToken) would be more honest. Minor nit though.

Mitch Denny and others added 4 commits March 6, 2026 11:44
After successful project creation via 'aspire init' or 'aspire new', prompt
the user to configure AI agent environments. The prompt is skipped in
non-interactive mode.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

# Conflicts:
#	src/Aspire.Cli/Resources/InitCommandStrings.Designer.cs
#	src/Aspire.Cli/Resources/InitCommandStrings.resx
#	src/Aspire.Cli/Resources/xlf/InitCommandStrings.cs.xlf
#	src/Aspire.Cli/Resources/xlf/InitCommandStrings.de.xlf
#	src/Aspire.Cli/Resources/xlf/InitCommandStrings.es.xlf
#	src/Aspire.Cli/Resources/xlf/InitCommandStrings.fr.xlf
#	src/Aspire.Cli/Resources/xlf/InitCommandStrings.it.xlf
#	src/Aspire.Cli/Resources/xlf/InitCommandStrings.ja.xlf
#	src/Aspire.Cli/Resources/xlf/InitCommandStrings.ko.xlf
#	src/Aspire.Cli/Resources/xlf/InitCommandStrings.pl.xlf
#	src/Aspire.Cli/Resources/xlf/InitCommandStrings.pt-BR.xlf
#	src/Aspire.Cli/Resources/xlf/InitCommandStrings.ru.xlf
#	src/Aspire.Cli/Resources/xlf/InitCommandStrings.tr.xlf
#	src/Aspire.Cli/Resources/xlf/InitCommandStrings.zh-Hans.xlf
#	src/Aspire.Cli/Resources/xlf/InitCommandStrings.zh-Hant.xlf
Unit tests should not prompt for interactive input. This prevents the
agent init prompt from blocking tests that use ConsoleInteractionService.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add DeclineAgentInitPrompt() shared helper to Hex1bTestHelpers.
Insert prompt handling in all CLI E2E and deployment E2E tests that
use aspire new or aspire init. Also add RunAspireInit helper to
DeploymentE2ETestHelpers.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Extract shared PromptAndChainAsync method on AgentInitCommand,
  removing duplicate PromptAndRunAgentInitAsync from InitCommand
  and NewCommand
- Remove unused ParseResult parameter from the chaining overload
- PR description will be updated to reflect defaultValue: true
  (opt-out behavior, pressing Enter accepts agent init)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
internal async Task<int> PromptAndChainAsync(
ICliHostEnvironment hostEnvironment,
IInteractionService interactionService,
string promptString,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The text passed from both places is the same. IMO remove this parameter, add the text to SharedCommandStrings and hardcode inside this method.

ICliHostEnvironment hostEnvironment,
IInteractionService interactionService,
string promptString,
int previousResult,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rename to previousResultExitCode to make clearer what it is

.Enter()
.WaitUntil(s => waitingForTestPrompt.Search(s).Count > 0, TimeSpan.FromSeconds(10))
.Enter()
.DeclineAgentInitPrompt()
Copy link
Member

@JamesNK JamesNK Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new agent prompt required updating 50+ tests.

Something I've been thinking about is there should be an E2E test helper method for calling aspire new. It enscapsulates all the CLI interactions involved with running aspire new.

If we had that method, and called it from all the end to end tests, then changes to aspire new (responding to new prompts, or changes in text) would only require updating one helper method. And not every test.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have an agent looking at this.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

… param

- Move PromptRunAgentInit from InitCommandStrings/NewCommandStrings to
  SharedCommandStrings and hardcode inside PromptAndChainAsync
- Remove promptString parameter from PromptAndChainAsync
- Rename previousResult to previousResultExitCode for clarity

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@radical radical mentioned this pull request Mar 11, 2026
16 tasks
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.

CLI first run - suggest running aspire agent init

4 participants