Skip to content

Cherry-pick VS Code extension fixes from main to release/13.2#14846

Merged
adamint merged 2 commits intodotnet:release/13.2from
adamint:dev/adamint/cherry-pick-extension-to-13.2
Mar 2, 2026
Merged

Cherry-pick VS Code extension fixes from main to release/13.2#14846
adamint merged 2 commits intodotnet:release/13.2from
adamint:dev/adamint/cherry-pick-extension-to-13.2

Conversation

@adamint
Copy link
Member

@adamint adamint commented Mar 2, 2026

Description

Cherry-picks VS Code extension commits from main that are missing in release/13.2:

These are the only extension-touching commits in main not already in release/13.2 (excluding PRs being separately retargeted).

Checklist

  • Is this feature complete?
    • Yes. Ready to ship.
    • No. Follow-up changes expected.
  • Are you including unit tests for the changes and scenario tests if relevant?
    • Yes
    • No — cherry-picks of already-merged and tested PRs
  • Did you add public API?
    • No
  • Does the change make any security assumptions or guarantees?
    • No
  • Does the change require an update in our Aspire docs?
    • No

adamint and others added 2 commits March 2, 2026 12:48
Check default installation directories (~/.aspire/bin, ~/.dotnet/tools) when the
Aspire CLI is not found on the system PATH. If found at a default location, the
VS Code setting is auto-updated. If later found on PATH, the setting is cleared.

Resolution order: configured custom path > system PATH > default install paths.

Fixes dotnet#14235
…n on AppHost restart (dotnet#14548)

* Fix JSON-RPC error on disconnect and auto-restart debug session on AppHost restart

* Update extension/src/debugger/AspireDebugSession.ts

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

* Update extension/src/debugger/AspireDebugSession.ts

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

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings March 2, 2026 17:48
@github-actions
Copy link
Contributor

github-actions bot commented Mar 2, 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 -- 14846

Or

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

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

Cherry-picks two VS Code extension fixes into release/13.2 by centralizing Aspire CLI path resolution (including default install locations) and improving debug-session lifecycle behavior (disconnect handling + auto-restart on AppHost restart).

Changes:

  • Add cliPath.ts with resolveCliPath() to locate the Aspire CLI (configured path → PATH → default install paths) and optionally update VS Code settings.
  • Update terminal/command/debug flows to use async CLI path resolution, including new localization for “CLI found at default path”.
  • Improve debug session disposal behavior and restart Aspire debug session when the AppHost terminates unexpectedly.

Reviewed changes

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

Show a summary per file
File Description
extension/src/utils/workspace.ts Switch CLI availability check to centralized resolver and add default-path UX messaging.
extension/src/utils/configInfoProvider.ts Use resolved CLI path for aspire config info --json.
extension/src/utils/cliPath.ts New module implementing CLI path resolution and settings updates, plus testable dependency injection.
extension/src/utils/AspireTerminalProvider.ts Make CLI path retrieval async via resolveCliPath(); terminal command sender awaits path resolution.
extension/src/test/cliPath.test.ts Unit tests covering resolution order and settings update/clear behavior.
extension/src/test/aspireTerminalProvider.test.ts Update tests to stub resolveCliPath() rather than stubbing VS Code configuration.
extension/src/loc/strings.ts Add localized string for “CLI found at default path”.
extension/src/extension.ts Update CLI availability checks + debug config provider construction.
extension/src/debugger/AspireDebugSession.ts Guard against double-dispose, catch stopCli errors, and restart Aspire session when AppHost terminates unexpectedly.
extension/src/debugger/AspireDebugConfigurationProvider.ts Remove terminal-provider dependency; rely on centralized CLI check.
extension/src/commands/add.ts Await async terminal command dispatch.
extension/src/commands/deploy.ts Await async terminal command dispatch.
extension/src/commands/init.ts Await async terminal command dispatch.
extension/src/commands/new.ts Await async terminal command dispatch.
extension/src/commands/publish.ts Await async terminal command dispatch.
extension/src/commands/update.ts Await async terminal command dispatch.
extension/package.nls.json Add string entry for default-path CLI message.
extension/loc/xlf/aspire-vscode.xlf Add XLF source string entry for default-path CLI message.
Comments suppressed due to low confidence (1)

extension/src/extension.ts:123

  • tryExecuteCommand() calls checkCliAvailableOrRedirect() (which runs resolveCliPath and executes aspire --version), and the invoked command then resolves the CLI path again via terminalProvider.getAspireCliExecutablePath(). This doubles the CLI resolution/exec overhead on every command. Consider returning and reusing the resolved cliPath from checkCliAvailableOrRedirect (or caching resolveCliPath for the duration of a command invocation) so resolution is performed only once per command.
    if (!cliCheckExcludedCommands.includes(commandName)) {
      const result = await checkCliAvailableOrRedirect();
      if (!result.available) {
        return;
      }
    }

    await command(terminalProvider);

* Gets the VS Code configuration setting for the Aspire CLI path.
*/
export function getConfiguredCliPath(): string {
return vscode.workspace.getConfiguration('aspire').get<string>('aspireCliExecutablePath', '').trim();
Copy link

Copilot AI Mar 2, 2026

Choose a reason for hiding this comment

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

getConfiguredCliPath() only trims whitespace; it no longer normalizes common user inputs like surrounding single/double quotes (the previous CLI availability check stripped them). If a user sets aspireCliExecutablePath to something like "C:\Program Files\Aspire\aspire.exe" (including quotes), resolveCliPath will treat it as invalid and repeatedly fall back to PATH/defaults while leaving the bad setting in place. Consider stripping one pair of surrounding quotes here (or in resolveCliPath) and optionally persisting the sanitized value back to settings.

Suggested change
return vscode.workspace.getConfiguration('aspire').get<string>('aspireCliExecutablePath', '').trim();
const rawPath = vscode.workspace.getConfiguration('aspire').get<string>('aspireCliExecutablePath', '').trim();
// Normalize common user input: strip one pair of surrounding quotes if present.
if (rawPath.length >= 2) {
const firstChar = rawPath[0];
const lastChar = rawPath[rawPath.length - 1];
if ((firstChar === '"' && lastChar === '"') || (firstChar === '\'' && lastChar === '\'')) {
return rawPath.substring(1, rawPath.length - 1);
}
}
return rawPath;

Copilot uses AI. Check for mistakes.
Comment on lines +283 to +288
if (result.available) {
// Show informational message if CLI was found at default path (not on PATH)
if (result.source === 'default-install') {
extensionLogOutputChannel.info(`Using Aspire CLI from default install location: ${result.cliPath}`);
vscode.window.showInformationMessage(cliFoundAtDefaultPath(result.cliPath));
}
Copy link

Copilot AI Mar 2, 2026

Choose a reason for hiding this comment

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

checkCliAvailableOrRedirect() shows an information message every time it resolves the CLI from a default install path. Since this check runs on every command/debug start, users without Aspire on PATH will likely get repeated notifications. Consider showing this message only when the setting is first auto-updated (configuredPath was empty/different) or gating it to once per session.

Copilot uses AI. Check for mistakes.
Comment on lines 95 to 99
if (isDirectory(appHostPath)) {
this.sendMessageWithEmoji("📁", launchingWithDirectory(appHostPath));

this.spawnRunCommand(args, appHostPath, noDebug);
void this.spawnRunCommand(args, appHostPath, noDebug);
}
Copy link

Copilot AI Mar 2, 2026

Choose a reason for hiding this comment

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

handleMessage() starts spawnRunCommand() with void and no error handling. Since spawnRunCommand is now async (awaiting CLI path resolution), a rejection (e.g., config update failure during resolveCliPath) would become an unhandled promise rejection. Consider wrapping spawnRunCommand in a try/catch internally, or attaching a .catch(...) when calling it to log and surface a user-friendly error.

Copilot uses AI. Check for mistakes.
Comment on lines 101 to 106
this.sendMessageWithEmoji("📂", launchingWithAppHost(appHostPath));

const workspaceFolder = path.dirname(appHostPath);
args.push('--project', appHostPath);
this.spawnRunCommand(args, workspaceFolder, noDebug);
void this.spawnRunCommand(args, workspaceFolder, noDebug);
}
Copy link

Copilot AI Mar 2, 2026

Choose a reason for hiding this comment

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

Same as above: spawnRunCommand() is invoked with void and no .catch(...) in the file-path case, which can surface as an unhandled promise rejection if CLI path resolution or spawn setup fails. Consider handling the returned promise (or making spawnRunCommand non-throwing).

Copilot uses AI. Check for mistakes.
@adamint adamint merged commit ee83e99 into dotnet:release/13.2 Mar 2, 2026
351 checks passed
@dotnet-policy-service dotnet-policy-service bot added this to the 13.2 milestone Mar 2, 2026
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