Skip to content

Upgrade Spectre.Console to 0.56.0 to fix #17307 OSC8 link wrapping bug#18092

Closed
maddymontaquila wants to merge 1 commit into
mainfrom
maddymontaquila/investigate-issue-17307-spectre-fix
Closed

Upgrade Spectre.Console to 0.56.0 to fix #17307 OSC8 link wrapping bug#18092
maddymontaquila wants to merge 1 commit into
mainfrom
maddymontaquila/investigate-issue-17307-spectre-fix

Conversation

@maddymontaquila

Copy link
Copy Markdown
Contributor

Problem

Resolves #17307: The "Logs" and "Dashboard" links in aspire ps output are not clickable at default terminal window size (~80 characters).

Symptom: When running aspire ps in a terminal with default width, the OSC8 terminal links lose their clickability after being wrapped to the next line.

Root Cause

This is a known issue in Spectre.Console #2124, where OSC8 terminal link markup loses its link attributes when wrapped in grid cells during line-wrapping. The issue manifests when:

  • PsCommand.DisplayTable() renders Dashboard/Logs links using MarkupHelpers.SafeLink() (which wraps URLs in [link=URL]text[/] Spectre markup format)
  • Links are placed in table cells
  • Line wrapping occurs (triggered by narrow terminal width)
  • In Spectre.Console 0.55.2, wrapping causes links to lose their OSC8 attributes, rendering them unclickable

Solution

Upgrade Spectre.Console from 0.55.2 to 0.56.0.

The upstream fix was merged in Spectre.Console PR #2135 ("Preserve links in segments") on 2026-06-05. This fix properly preserves OSC8 link attributes across segment manipulation during text wrapping.

Changes

  • Directory.Packages.props line 132: Bumped Spectre.Console version from 0.55.2 to 0.56.0

Validation

Unit Tests: All 28 PsCommandTests passed without regression
E2E Tests: Both PsCommand end-to-end tests passed (3m 43s)
Upstream Fix: Verified in Spectre.Console 0.56.0 source

Related Issues & References

Code Impact

The fix is entirely upstream in Spectre.Console. No CLI code changes required. The following code paths benefit from this update:

  • src/Aspire.Cli/Commands/PsCommand.cs:394-443DisplayTable() method where Dashboard links are rendered
  • src/Aspire.Cli/Utils/MarkupHelpers.cs:18-30SafeLink() markup generation (now works correctly with 0.56.0)

Fixes: #17307

## Root Cause
The 'Logs' and 'Dashboard' links in 'aspire ps' output were not clickable at default terminal window size (80 chars). This is due to Spectre.Console #2124, where OSC8 terminal link markup loses its link attributes when wrapped in grid cells during line-wrapping.

## Solution
Upgrade Spectre.Console from 0.55.2 to 0.56.0, which includes the fix from Spectre PR #2135 ("Preserve links in segments", merged 2026-06-05). The 0.56.0 release includes proper OSC8 link preservation across segment manipulation during text wrapping.

## Verification
- Unit tests: All 28 PsCommandTests passed
- E2E tests: Both PsCommand e2e tests passed (3m 43s)
- Upstream fix: Spectre.Console 0.56.0 (published 2026-06-05) includes PR #2135 fix commit

Related issues:
- spectreconsole/spectre.console#2124
- spectreconsole/spectre.console#2135

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings June 10, 2026 18:15
@github-actions

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 -- 18092

Or

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

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 bumps the Spectre.Console dependency from 0.55.2 to 0.56.0 to resolve issue #17307, where OSC8 terminal hyperlinks in aspire ps output became unclickable when line-wrapping occurred at default terminal width. The fix is entirely upstream (spectreconsole/spectre.console#2135 — "Preserve links in segments"), requiring only a version bump with no Aspire code changes.

Changes:

  • Upgraded Spectre.Console package version from 0.55.2 to 0.56.0 in central package management
Show a summary per file
File Description
Directory.Packages.props Bumps Spectre.Console version from 0.55.2 to 0.56.0 to pick up the upstream OSC8 link-wrapping fix

Copilot's findings

  • Files reviewed: 1/1 changed files
  • Comments generated: 0

@github-actions

Copy link
Copy Markdown
Contributor

Re-running the failed jobs in the CI workflow for this pull request because 3 jobs were identified as retry-safe transient failures in the CI run attempt.
GitHub was asked to rerun all failed jobs for that attempt, and the rerun is being tracked in the rerun attempt.
The job links below point to the failed attempt jobs that matched the retry-safe transient failure rules.

Matched test failure patterns (1 test)
  • Aspire.Cli.EndToEnd.Tests.KubernetesDeployWithMySqlTests.DeployK8sWithMySql — Unable to access container registry during publish

@github-actions

Copy link
Copy Markdown
Contributor

CLI E2E Tests failed — 112 passed, 1 failed, 2 unknown (commit 67ccd98)

❌ Failed Tests

- Test Detail
DeployK8sWithMySql Recording · Job · CLI logs
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
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
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 #27296658095

@maddymontaquila maddymontaquila marked this pull request as draft June 10, 2026 19:11
@maddymontaquila

Copy link
Copy Markdown
Contributor Author

PR Testing Report

PR Information

CLI Version Verification

  • Expected Commit: 67ccd98
  • Installed Version: 13.5.0-pr.18092.g67ccd98c
  • Status: ✅ Verified

Changes Analyzed

Files Changed

  • Directory.Packages.props - Modified

Change Categories

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

Test Scenarios Executed

Scenario 1: Install and verify PR CLI

Objective: Download the dogfood build and confirm the installed binary matches the PR head commit.
Coverage Type: Happy path
Status: ✅ Passed

Evidence:

  • install.log

Observations:

  • The installed binary reported 13.5.0-pr.18092.g67ccd98c, which contains the PR commit prefix.

Scenario 2: CLI help/output smoke test

Objective: Exercise Spectre.Console-driven help output at a narrow terminal width.
Coverage Type: Happy path
Status: ✅ Passed

Evidence:

  • help.log
  • new-help.log

Observations:

  • aspire --help rendered successfully.
  • aspire new aspire-empty --help exposed the non-interactive flags needed for automation, including --language and --non-interactive.

Scenario 3: Template creation smoke test

Objective: Create a fresh aspire-empty app in a temp directory using the PR hive and non-interactive flags.
Coverage Type: Happy path
Status: ✅ Passed

Evidence:

  • new.log
  • Generated files under PrSmoke/

Observations:

  • The scaffold completed successfully once --language csharp --non-interactive were supplied.
  • Generated layout included apphost.cs, aspire.config.json, apphost.run.json, and nuget.config.

Summary

Scenario Status Notes
Scenario 1 ✅ Passed Version matched the PR head commit
Scenario 2 ✅ Passed Help output rendered cleanly
Scenario 3 ✅ Passed Scaffold succeeded with non-interactive flags

Overall Result

✅ PR VERIFIED

Recommendations

  • None.

@maddymontaquila

Copy link
Copy Markdown
Contributor Author

Follow-up: this fixes clickability, but it still does not address wrapped URLs in narrow table cells. The ps dashboard column still renders the full URL text, so the visible output truncates/splits on narrow terminals. In Aspire, we usually avoid that by using a shorter visible label and keeping the full URL only as the link target (for example MarkupHelpers.SafeLink(..., title: "Open dashboard") or ... title: "Aspire documentation").

@microsoft-github-policy-service microsoft-github-policy-service Bot added this to the 13.5 milestone Jun 10, 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.

[AspireE2E]After running aspire ps with the terminal window at its default size, the "Logs" and "Dashboard" links are not clickable.

2 participants