Skip to content

[release/13.3] Show AppHost code lenses without opening the panel; add Open Dashboard / View Logs lenses#16682

Open
aspire-repo-bot[bot] wants to merge 5 commits intorelease/13.3from
backport/pr-16667-to-release/13.3
Open

[release/13.3] Show AppHost code lenses without opening the panel; add Open Dashboard / View Logs lenses#16682
aspire-repo-bot[bot] wants to merge 5 commits intorelease/13.3from
backport/pr-16667-to-release/13.3

Conversation

@aspire-repo-bot
Copy link
Copy Markdown
Contributor

Backport of #16667 to release/13.3

/cc @adamint

Customer Impact

Testing

Risk

Regression?

adamint and others added 5 commits May 1, 2026 22:07
When a brand-new C# or TS/JS AppHost file was opened, the resource code
lenses didn't appear and no live data was fetched until the user opened
the Running AppHosts panel. The data repository was gating both
'aspire describe --follow' and 'aspire ps' polling solely on panel
visibility.

Open the gates so they react to either signal:
- Add 'AppHostFilePresenceWatcher' that watches visible text editors and
  reports to 'AppHostDataRepository.setAppHostFileOpen' whenever any
  visible editor is detected as an AppHost file by the existing parsers.
- 'AppHostDataRepository._dataActive' is true when either the panel is
  visible OR an AppHost file is open, so describe/ps lifecycle now
  follows the union of both gates.

Also surface AppHost-level actions on the builder statement:
- 'AppHostResourceParser' gains an optional 'findBuilderStatementLine'
  hook. C# locates 'DistributedApplication.CreateBuilder' and TS/JS
  locates 'createBuilder('.
- 'AspireCodeLensProvider' renders 'Open Dashboard' and 'View Logs'
  lenses above the builder line whenever live data is available, routed
  through the matching running AppHost (path/dir match) so the right
  '--apphost' is targeted in multi-host scenarios.
- New extension commands 'aspire-vscode.codeLensOpenDashboard' and
  'aspire-vscode.codeLensViewAppHostLogs' wire the lenses through the
  existing tree provider and terminal helpers.

Tighten icon-to-label spacing in CodeLens titles by inserting a HAIR
SPACE (U+200A) between the codicon and the text in all 20 lens strings.
The CodeLens API exposes no other typography control, and U+200A adds
roughly one pixel of breathing room without disturbing translation.

Tests:
- New tests for the dual-gate behavior on 'AppHostDataRepository'.
- New tests for 'findBuilderStatementLine' in both parsers.
- 'findStatementStartLine' now skips '#:'-style file-scoped C# directives
  and blank lines so the builder lens lands on the actual statement.
- _resolveAppHostPathForDocument now returns undefined when the document
  cannot be tied to a running AppHost; the .cs source-path fallback
  (which the CLI cannot resolve into a project) is removed.
- Builder lenses (Open Dashboard / View Logs) only emit when a running
  AppHost is concretely matched, and emit even when the file has no
  Add* resource calls.
- AppHostFilePresenceWatcher now also reacts to onDidChangeTextDocument
  (debounced) so toggling AppHost-ness via edits is picked up without a
  visibility/save round-trip.
- 'Open Aspire Dashboard' capitalization aligned with the existing
  command.openDashboard string.
- New tests for AppHostFilePresenceWatcher (9), AspireCodeLensProvider
  builder lens (9) and AspireAppHostTreeProvider.findAppHostElement (9).
…erminal commands

- Send Ctrl+C (\x03) instead of Ctrl+U/Esc before sending commands to the
  Aspire terminal, so a new command interrupts any foreground Aspire process
  (e.g. `aspire logs --follow`) instead of being delivered to its stdin.
- Anchor resource code lenses at the resource's own `.AddXyz("name")` call
  line instead of the chain's start line, so chained resources like
  `builder.AddPostgres("pg").AddDatabase("db")` no longer stack two
  state/action lens sets on the same line. Pipeline steps still anchor at
  the statement start.
- Dedupe gutter decorations by (line, category) so resources sharing a line
  don't double-stack identical icons.
- Replace the pale-green check used for Finished/Exited/Stopped resources
  with a clearly distinct icon: a grey hollow circle with a check inside in
  the editor gutter, and the `circle-outline` codicon (matching the
  `Stopped` code-lens label) in the tree view. Previously the pale-green
  and bright-green checks were nearly indistinguishable at gutter icon size,
  making stopped resources look like they were still running.
…ed icon assertions

- aspireCodeLensProvider.test.ts: build test paths via path.join(path.sep, ...)
  so vscode.Uri.file().fsPath (which uses backslashes on Windows) matches the
  hostPath dirname. Previously the Windows CI run failed all 3 'emits builder
  lenses' tests with 0 !== 2 because '/repo/AppHost' (forward) never equaled
  '\repo\AppHost' (back). Two other tests were silently passing for the wrong
  reason; updated them too so they really exercise the no-match branch.
- appHostTreeView.test.ts: update the two Finished-state icon assertions to
  expect 'circle-outline' (the new hollow-circle stopped icon) instead of
  'pass'. Mirrors the previous commit's tree-view icon change.
- Skip DistributedApplication.CreateBuilder/createBuilder matches in
  // and /* */ comment lines so the AppHost-level code-lens anchors
  on real builder lines.
- Use additionalArgs (per-platform escaping) for the codeLensViewAppHostLogs
  command instead of interpolating the path into a shell command string.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings May 1, 2026 22:07
@aspire-repo-bot aspire-repo-bot Bot requested a review from adamint as a code owner May 1, 2026 22:07
@aspire-repo-bot aspire-repo-bot Bot review requested due to automatic review settings May 1, 2026 22:07
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 1, 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/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.sh | bash -s -- 16682

Or

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

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 1, 2026

🎬 CLI E2E Test Recordings — 66 recordings uploaded (commit 4d4489d)

View all recordings
Status Test Recording
AddPackageInteractiveWhileAppHostRunningDetached ▶️ View Recording
AddPackageWhileAppHostRunningDetached ▶️ View Recording
AgentCommands_AllHelpOutputs_AreCorrect ▶️ View Recording
AgentInitCommand_DefaultSelection_InstallsSkillOnly ▶️ View Recording
AgentInitCommand_MigratesDeprecatedConfig ▶️ View Recording
AspireAddPackageVersionToDirectoryPackagesProps ▶️ View Recording
AspireUpdateRemovesAppHostPackageVersionFromDirectoryPackagesProps ▶️ View Recording
Banner_DisplayedOnFirstRun ▶️ View Recording
Banner_DisplayedWithExplicitFlag ▶️ View Recording
Banner_NotDisplayedWithNoLogoFlag ▶️ View Recording
CertificatesClean_RemovesCertificates ▶️ View Recording
CertificatesTrust_WithNoCert_CreatesAndTrustsCertificate ▶️ View Recording
CertificatesTrust_WithUntrustedCert_TrustsCertificate ▶️ View Recording
ConfigSetGet_CreatesNestedJsonFormat ▶️ View Recording
CreateAndRunAspireStarterProject ▶️ View Recording
CreateAndRunAspireStarterProjectWithBundle ▶️ View Recording
CreateAndRunEmptyAppHostProject ▶️ View Recording
CreateAndRunJavaEmptyAppHostProject ▶️ View Recording
CreateAndRunJsReactProject ▶️ View Recording
CreateAndRunPythonReactProject ▶️ View Recording
CreateAndRunTypeScriptEmptyAppHostProject ▶️ View Recording
CreateAndRunTypeScriptStarterProject ▶️ View Recording
CreateJavaAppHostWithViteApp ▶️ View Recording
CreateTypeScriptAppHostWithViteApp_UsesConfiguredToolchain ▶️ View Recording
DashboardRunWithOtelTracesReturnsNoTraces ▶️ View Recording
DescribeCommandResolvesReplicaNames ▶️ View Recording
DescribeCommandShowsRunningResources ▶️ View Recording
DetachFormatJsonProducesValidJson ▶️ View Recording
DetachFormatJsonProducesValidJsonWhenRestartingExistingInstance ▶️ View Recording
DoListStepsShowsPipelineSteps ▶️ View Recording
DocsCommand_RendersInteractiveMarkdownFromLocalSource ▶️ View Recording
DoctorCommand_DetectsDeprecatedAgentConfig ▶️ View Recording
DoctorCommand_TypeScriptAppHostReportsMissingConfiguredToolchain ▶️ View Recording
DoctorCommand_WithSslCertDir_ShowsTrusted ▶️ View Recording
DoctorCommand_WithoutSslCertDir_ShowsPartiallyTrusted ▶️ View Recording
GlobalMigration_HandlesCommentsAndTrailingCommas ▶️ View Recording
GlobalMigration_HandlesMalformedLegacyJson ▶️ View Recording
GlobalMigration_PreservesAllValueTypes ▶️ View Recording
GlobalMigration_SkipsWhenNewConfigExists ▶️ View Recording
GlobalSettings_MigratedFromLegacyFormat ▶️ View Recording
InitTypeScriptAppHost_AugmentsExistingViteRepoAtRoot ▶️ View Recording
InteractiveCSharpInitCreatesExpectedFiles ▶️ View Recording
InvalidAppHostPathWithComments_IsHealedOnRun ▶️ View Recording
LegacySettingsMigration_AdjustsRelativeAppHostPath ▶️ View Recording
LogsCommandShowsResourceLogs ▶️ View Recording
OtelLogsReturnsStructuredLogsFromStarterAppCore ▶️ View Recording
PsCommandListsRunningAppHost ▶️ View Recording
PsFormatJsonOutputsOnlyJsonToStdout ▶️ View Recording
PublishWithConfigureEnvFileUpdatesEnvOutput ▶️ View Recording
PublishWithDockerComposeServiceCallbackSucceeds ▶️ View Recording
PublishWithoutOutputPathUsesAppHostDirectoryDefault ▶️ View Recording
RestoreGeneratesSdkFiles ▶️ View Recording
RestoreGeneratesSdkFiles_WithConfiguredToolchain ▶️ View Recording
RestoreRefreshesGeneratedSdkAfterAddingIntegration ▶️ View Recording
RestoreSupportsConfigOnlyHelperPackageAndCrossPackageTypes ▶️ View Recording
RunFromParentDirectory_UsesExistingConfigNearAppHost ▶️ View Recording
SecretCrudOnDotNetAppHost ▶️ View Recording
SecretCrudOnTypeScriptAppHost ▶️ View Recording
StagingChannel_ConfigureAndVerifySettings_ThenSwitchChannels ▶️ View Recording
StartAndWaitForTypeScriptSqlServerAppHostWithNativeAssets ▶️ View Recording
StopAllAppHostsFromAppHostDirectory ▶️ View Recording
StopAllAppHostsFromUnrelatedDirectory ▶️ View Recording
StopNonInteractiveMultipleAppHostsShowsError ▶️ View Recording
StopNonInteractiveSingleAppHost ▶️ View Recording
StopWithNoRunningAppHostExitsSuccessfully ▶️ View Recording
UnAwaitedChainsCompileWithAutoResolvePromises ▶️ View Recording

📹 Recordings uploaded automatically from CI run #25235254717

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.

1 participant