Skip to content

Add VS Code attach debugger resource action#18602

Draft
adamint wants to merge 18 commits into
microsoft:mainfrom
adamint:adamint/issue18538-vscode-debug-shortcut
Draft

Add VS Code attach debugger resource action#18602
adamint wants to merge 18 commits into
microsoft:mainfrom
adamint:adamint/issue18538-vscode-debug-shortcut

Conversation

@adamint

@adamint adamint commented Jul 1, 2026

Copy link
Copy Markdown
Member

Summary

Adds a VS Code Attach debugger resource action for running .NET project resources in the Aspire view.

The action builds a CoreCLR attach configuration from the selected resource, routes through the existing debugger service, and keeps the command hidden unless the current CLI/extension capability path can support it.

Fixes #18538.

Changes

  • Adds the attach-debugger resource action for C# project resources.
  • Keeps stale-resource handling user-visible with a localized warning.
  • Makes C# attach capability explicit instead of relying on an implicit default.
  • Adds assembly-name handling for project outputs with AssemblyName attributes.
  • Expands debugger telemetry redaction and client-version coverage.
  • Preserves dashboard telemetry correlation ids so operation_id stays useful across the dashboard route.
  • Adds coverage for startDebugging returning false and rejecting.
  • Updates the VS Code extension changelog.

Validation

  • PATH="$PWD/.dotnet:$PWD/.dotnet/x64:$PATH" ./extension/build.sh
  • cd extension && corepack yarn run compile-tests && corepack yarn run lint
  • Short-path VS Code unit validation in /tmp/aspire-pr18602-test: 1136 passing, 1 pending.
  • Targeted attach/telemetry VS Code host subsets: 56 passing.
  • Dashboard telemetry route + utility tests: 38 passing.
  • Utility subset after Windows cwd fix: 21 passing.
  • Packaged PR VSIX packageSurface E2E: 7/7 passed. Evidence: /Users/adamratzman/.copilot/session-state/4263d434-e095-4dc4-8bb2-7c57d71bc533/files/pr18602-e2e/all/.
  • Resume check for conditional attach path: cd /tmp/a18602v/extension && yarn run compile-tests && yarn run compile && yarn run lint && yarn run unit-test --run out/test/appHostTreeView.test.js --grep 'attachDebuggerToResource ignores conditional AssemblyName values': 1 passing.
  • CI at ecb3b65f25bc9676777a05c83df507465251d528: 328 success, 3 skipped, 0 pending, 0 failures.

Manual follow-up

Still draft until I do a live CoreCLR attach pass from a running AppHost resource. The current proof covers the real Extension Host/package surface and unit-level debugger configuration, but not the full live debugger attach loop.

Adam Ratzman and others added 4 commits June 29, 2026 15:52
…e names

Replace the implicit `microsoft-aspire.aspire-vscode/` extension-id prefix
that VS Code's `TelemetryLogger` adds to every telemetry event with an
explicit, dashboard-native namespace:

  * Extension-emitted events  → `aspire/vscode/<area>/<event>`
  * Dashboard passthrough     → `aspire/dashboard/<route>`

Route every send through `reporter.sendDangerousTelemetryEvent` /
`sendDangerousTelemetryErrorEvent`. Those bypass the prefix-applying
`TelemetryLogger` but also bypass the reporter's built-in opt-in gate, so
gating is enforced explicitly via `reporter.telemetryLevel`:

  * `'all'`   → regular and error events emit
  * `'error'` → only error events emit
  * `'crash'`/`'off'` → nothing emits

Renames cover the registry (`extension/src/utils/telemetryRegistry.ts`),
all 22 callsites, the data classification catalog
(`extension/telemetry.json`), and every test fake. Existing event
schemas / property unions are unchanged; only the wire names move.

Adds proof tests in `extension/src/test/telemetry.test.ts` pinning:

  * `sendTelemetryEvent` routes through `sendDangerousTelemetryEvent`
    with the registry-declared name and no extension-id prefix
  * `sendTelemetryErrorEvent` routes through the dangerous error channel
  * dashboard-namespaced events emit verbatim
  * `'off'` / `'crash'` suppress everything; `'error'` allows only error
    events

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Fail test telemetry immediately if the regular sendTelemetryEvent path is used, proving the extension bypasses VS Code's extension-id prefix channel.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add explicit property value sanitization and restore common telemetry dimensions before using the dangerous telemetry send path.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add a tree context action for running .NET project resources that starts a CoreCLR attach session by process name, with stale-resource and C# debugger gating.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings July 1, 2026 20:16
@github-actions

github-actions Bot commented Jul 1, 2026

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

Or

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

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 adds the first VS Code extension lane for #18538: a right-click Attach debugger action on running .NET project resources in the Aspire panel. It builds a CoreCLR attach debug configuration that targets the project's process by processName (best-effort resolving <AssemblyName> from the project file), rather than executable.pid, because DCP reports the dotnet run launcher PID rather than the child app process. The action is gated on a running top-level Project resource with a dotnet executable and a .csproj/.fsproj/.vbproj path, and only when the C# extension is installed; it re-resolves the latest resource before attaching so stale/ambiguous/missing resources fail closed with a warning.

Bundled alongside the feature is a broad telemetry overhaul: every event is renamed to its final wire name (aspire/vscode/... and aspire/dashboard/...) and routed through sendDangerousTelemetryEvent/sendDangerousTelemetryErrorEvent to bypass VS Code's automatic <extensionId>/ prefix, with manual opt-in gating (telemetryLevel), manual common properties, and explicit value sanitization.

Changes:

  • Add aspire-vscode.attachDebuggerToResource command, menu contribution (canAttachDebugger context value), attachability helpers, and the attach execution flow with latest-resource re-resolution.
  • Rename all telemetry events to final wire names and route them through the "dangerous" send path with explicit gating/sanitization and manually-added common properties.
  • Add localized strings and extensive unit tests for both the attach flow and the telemetry changes.
Show a summary per file
File Description
extension/src/views/AspireAppHostTreeProvider.ts Core attach logic: attachability helpers, process-name derivation, attachDebuggerToResource, latest-resource resolution; propagates appHostPath through tree items.
extension/src/extension.ts Registers the new attach command; renames the extension/activated telemetry event.
extension/package.json Contributes the command, hidden palette entry, and view/item/context menu item; reorders action groups.
extension/package.nls.json / extension/src/loc/strings.ts / extension/loc/xlf/aspire-vscode.xlf Adds/regenerates localized strings for the attach action.
extension/src/utils/telemetry.ts Switches to dangerous-send path, adds manual gating, common properties, and value sanitization; hard-codes telemetry client version.
extension/src/utils/telemetryRegistry.ts Renames event schema keys to final aspire/vscode/... and aspire/dashboard/... wire names; documents the convention.
extension/telemetry.json Updates classification inventory keys to the new wire names.
extension/src/dcp/DashboardTelemetryPassthrough.ts / AspireDcpServer.ts / AspireDebugSession.ts / AppHostLaunchService.ts / AppHostsViewTelemetry.ts / meaningfulEngagement.ts / appHostDiscovery.ts / workspace.ts / interactionService.ts Update event-name call sites and passthrough comments to the new namespaces.
extension/src/test/*.test.ts, extension/src/test-e2e/packageSurface.e2e.test.ts Extensive tests for the attach flow, telemetry gating/sanitization/naming, and the manifest/surface contributions.

Review details

  • Files reviewed: 29/29 changed files
  • Comments generated: 3
  • Review effort level: Medium

Comment on lines +26 to +33
// EVENT NAMING CONVENTION:
// Extension-emitted events are namespaced under `aspire/vscode/...` and
// dashboard passthrough events are namespaced under `aspire/dashboard/...`,
// matching what other Aspire dashboard hosts (Visual Studio, C# Dev Kit)
// emit. The names here are the FINAL wire names — the helpers in
// `telemetry.ts` deliberately bypass VS Code's automatic
// `<extensionId>/<eventName>` prefix (added by `vscode.env.createTelemetryLogger`)
// so this convention is what reaches the telemetry backend.
});

test('attachDebuggerToResource uses AssemblyName when the project file declares one', async () => {
const directory = fs.mkdtempSync(path.join(process.cwd(), '.assembly-name-test-'));
'common.os': os.platform(),
'common.nodeArch': os.arch(),
'common.platformversion': os.release().replace(/^(\d+)(\.\d+)?(\.\d+)?(.*)/, '$1$2$3'),
'common.telemetryclientversion': '1.5.1',
@github-actions

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt.

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

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings July 1, 2026 23:36
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

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.

Review details

  • Files reviewed: 30/30 changed files
  • Comments generated: 1
  • Review effort level: Medium

Comment thread extension/src/utils/telemetry.ts Outdated
.replace(/([?&]sig=)[^&\s"',;}]+/gi, '$1<redacted>')
.replace(/\b(authorization\s*:\s*bearer\s+)[^\s"',;}]+/gi, '$1<redacted>')
.replace(/\b(bearer\s+)[A-Za-z0-9._~+/=-]+/gi, '$1<redacted>')
.replace(/\b[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}\b/gi, '<guid>');
Copilot AI review requested due to automatic review settings July 1, 2026 23:45

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.

Review details

  • Files reviewed: 30/30 changed files
  • Comments generated: 1
  • Review effort level: Medium

Comment on lines 580 to 581
// telemetry pipeline (consistent with the synchronous launch-failure path
// above and the dashboard fault path in DashboardTelemetryPassthrough).
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@adamint

adamint commented Jul 2, 2026

Copy link
Copy Markdown
Member Author

I tried to place these as inline tracking comments, but GitHub rejected new inline comments because there is already a pending review draft for this user on the PR. I kept the tracking here instead while the branch was fixed:

  1. The handled attach guard failures in attachDebuggerToResource should return a failure result for command telemetry instead of plain void, otherwise withCommandTelemetry records user-visible attach failures as successful invocations.
  2. The home-directory sanitizer needed coverage and a fix for usernames with spaces; paths like /Users/Alice Smith/project or C:\Users\Alice Smith\project could leave part of the username in telemetry after the dangerous-send path.

These were fixed before the later Windows punctuation redaction follow-up. This is a top-level tracking comment, so there is no review thread to resolve; final tracking is in #18602 (comment).

@adamint

adamint commented Jul 2, 2026

Copy link
Copy Markdown
Member Author

Pushed 8f4fe85 with the Windows telemetry redaction fix. Windows CI caught that the home-directory sanitizer could cross punctuation/text between two C:\Users\... paths; the parser now keeps punctuation boundaries intact and the regression is covered.

Validation on the live head passed locally: compile-tests, lint, compile, and full telemetry.test (31 passing). gh pr checks is green on 8f4fe85 (328 success / 0 pending / 3 skipped / 0 failed), and the review/test fleet found no blocking agent-owned follow-up.

Remaining non-agent gates: live CoreCLR attach/manual readiness pass, plus telemetry/reviewer sign-off for the common.* properties and dangerous-send sanitizer parity.

…ed home usernames

The attachDebuggerToResource command handles three user-visible guard failures
(stale/missing resource, resource no longer attachable, and missing C# extension)
by showing a warning and returning. Because the command is registered through
withCommandTelemetry, returning void recorded these as a success outcome. Return a
handled-failure object ({ success: false, errorKind }) so each is recorded as an
error outcome with a specific error_kind, without triggering VS Code's generic
command-failed notification. The genuine startDebugging-declined path still throws.

Also fix sanitizeTelemetryValue home-directory redaction, which stopped at the
first whitespace and leaked the rest of a username that contains spaces (and the
following path). Redact the full username segment up to the next same-type path
separator for both POSIX and Windows homes, while leaving unrelated following path
segments intact.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings July 2, 2026 20:14

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.

Review details

  • Files reviewed: 30/30 changed files
  • Comments generated: 0 new
  • Review effort level: Medium

adamint and others added 2 commits July 2, 2026 14:47
Ignore AssemblyName values that depend on unevaluated MSBuild conditions when building VS Code attach configurations. Preserve the project filename fallback when no unconditional literal AssemblyName is available.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Keep the attach debugger AssemblyName tests out of the repository working tree so aborted runs do not leave .assembly-name-test-* directories behind and concurrent test runs avoid repo-local temp path collisions.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings July 3, 2026 02:09

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.

Review details

  • Files reviewed: 30/30 changed files
  • Comments generated: 0 new
  • Review effort level: Medium

adamint and others added 2 commits July 2, 2026 20:28
Keep the last unconditional simple AssemblyName when building the CoreCLR attach process name, matching MSBuild property override ordering, and cover the regression in the attach debugger tests.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings July 3, 2026 02:46

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.

Review details

  • Files reviewed: 30/30 changed files
  • Comments generated: 0 new
  • Review effort level: Medium

adamint and others added 2 commits July 2, 2026 21:07
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings July 4, 2026 15:42

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.

Review details

  • Files reviewed: 30/30 changed files
  • Comments generated: 0 new
  • Review effort level: Medium

adamint and others added 2 commits July 4, 2026 10:14
Restore VS Code common telemetry dimensions on the dangerous send path and make the current-home sanitizer test use USERPROFILE on Windows.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Make the optional VS Code product metadata lookup best-effort so malformed product.json cannot fail extension activation.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings July 4, 2026 16:36

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.

Review details

  • Files reviewed: 30/30 changed files
  • Comments generated: 0 new
  • Review effort level: Medium

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[vscode] add a shortcut to attach debugger to a running apphost

2 participants