Chain aspire agent init from aspire init on success#14629
Chain aspire agent init from aspire init on success#14629mitchdenny merged 5 commits intorelease/13.2from
Conversation
|
🚀 Dogfood this PR with:
curl -fsSL https://raw.githubusercontent.com/dotnet/aspire/main/eng/scripts/get-aspire-cli-pr.sh | bash -s -- 14629Or
iex "& { $(irm https://raw.githubusercontent.com/dotnet/aspire/main/eng/scripts/get-aspire-cli-pr.ps1) } 14629" |
There was a problem hiding this comment.
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
InitCommandthat chains intoAgentInitCommandwhen user accepts - Added localization string
PromptRunAgentInitto 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
|
/deployment-test |
|
🚀 Deployment tests starting on PR #14629... This will deploy to real Azure infrastructure. Results will be posted here when complete. |
|
❌ Deployment E2E Tests failed Summary: 23 passed, 1 failed, 0 cancelled Passed Tests
Failed Tests
🎬 Terminal Recordings
|
JamesNK
left a comment
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
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; | ||
| } |
There was a problem hiding this comment.
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) |
There was a problem hiding this comment.
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.
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, |
There was a problem hiding this comment.
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, |
There was a problem hiding this comment.
Rename to previousResultExitCode to make clearer what it is
| .Enter() | ||
| .WaitUntil(s => waitingForTestPrompt.Search(s).Count > 0, TimeSpan.FromSeconds(10)) | ||
| .Enter() | ||
| .DeclineAgentInitPrompt() |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
I have an agent looking at this.
… 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>
Summary
After
aspire initoraspire newcompletes 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 sharedPromptAndChainAsynchelper that handles the prompt-then-delegate pattern in one placesrc/Aspire.Cli/Commands/InitCommand.cs: InjectAgentInitCommandand callPromptAndChainAsyncon successful initsrc/Aspire.Cli/Commands/NewCommand.cs: Same chaining pattern after successfulaspire newPromptRunAgentInitto resx, Designer.cs, and all xlf localization filesnonInteractive: trueto prevent the new prompt from hanging in non-interactive test environmentsAgentCommandTests.cs:InitCommand_ChainsIntoAgentInit_WhenUserAccepts— verifies agent init starts after user acceptsInitCommand_SkipsAgentInit_WhenUserDeclines— verifies clean exit when user declinesDesign Decisions
PromptAndChainAsynconAgentInitCommandconsolidates the prompt-then-delegate pattern (no duplication across commands)SupportsInteractiveInputcheck)true(opt-out) — pressing Enter accepts agent init to encourage adoptionCloses #14432