Skip to content

Add in-editor survey pane#322192

Merged
digitarald merged 15 commits into
mainfrom
digitarald/in-editor-pmf-survey
Jun 22, 2026
Merged

Add in-editor survey pane#322192
digitarald merged 15 commits into
mainfrom
digitarald/in-editor-pmf-survey

Conversation

@digitarald

@digitarald digitarald commented Jun 20, 2026

Copy link
Copy Markdown
Contributor

Summary

Moves in-product Copilot PMF surveys from a notification → external-URL flow into a native editor pane, following the same pattern as the Issue Reporter editor.

Architecture

  • EditorInput + EditorPane — Singleton, readonly, vscode-survey:/{surveyId} URI scheme
  • Two commands:
    • workbench.action.openSurvey — Developer-only (F1 visible, IsDevelopmentContext precondition + stable-build runtime guard)
    • _workbench.action.openCopilotSurvey — Internal programmatic command for extension use; accepts source argument validated against an allowlist
  • Extension integration — Copilot SurveyService.promptSurvey() notification now calls _workbench.action.openCopilotSurvey instead of vscode.env.openExternal
  • Sessions window — Opens in editorGroupsService.mainPart.activeGroup (same as Issue Reporter)

UI

  • Segmented control (Q1: PMF score) — Native radios visually hidden, labels styled with --vscode-radio-* tokens
  • List-row selection (Q2/Q3) — Full-width clickable <label> rows with hidden native radios, selected via :has(:checked) with full rectangular border
  • Responsive — Container queries: segment stacks vertically at 560px, 2-column list collapses to 1-column at 480px
  • High contrasthc-black/hc-light support with dashed focus indicators and contrastActiveBorder
  • Success state — Animated confirmation with role="status" + aria-live="polite", auto-close after 5s (longer for screen reader readout)

Telemetry

Single survey/submit event with flat fields:

Field Type Description
surveyId string Survey identifier (e.g. copilot-pmf)
source string Validated Copilot feature source (e.g. completions, panel.agent)
pmfScore number (0-4) Disappointment index: 0=not at all … 4=extremely
primaryBenefit string Selected value driver option ID
primaryFriction string Selected friction point option ID

Accessibility

  • AccessibleViewProviderId.Survey + AccessibilityVerbositySettingId.Survey
  • Help dialog (Alt+F1) with Tab/Arrow/Enter instructions
  • Focus restored to survey pane on help close
  • Native radio keyboard navigation preserved throughout

Security

  • Command source argument is validated against a known-sources allowlist; unknown values map to "unknown"
  • Dev command has runtime guard preventing execution in stable builds

How to test

  1. Build Code OSS (dev build)
  2. Command Palette → Developer: Open Survey
  3. Answer all 3 questions, click Submit
  4. Observe success state and auto-close after 5s

Files changed

File Description
src/vs/workbench/contrib/surveys/browser/survey.contribution.ts Pane registration, commands, source validation, a11y help
src/vs/workbench/contrib/surveys/browser/surveyEditorPane.ts Form rendering, interaction, submit, success state
src/vs/workbench/contrib/surveys/browser/surveyEditorInput.ts Singleton EditorInput with mutable source
src/vs/workbench/contrib/surveys/browser/surveyQuestions.ts Question schema + Copilot PMF definition
src/vs/workbench/contrib/surveys/browser/media/surveyEditorPane.css Full CSS with responsive, HC, animations
src/vs/workbench/workbench.desktop.main.ts Survey contribution import
src/vs/workbench/workbench.web.main.ts Survey contribution import
src/vs/sessions/sessions.desktop.main.ts Survey contribution import
src/vs/sessions/sessions.web.main.ts Survey contribution import
src/vs/platform/accessibility/browser/accessibleView.ts Added Survey provider ID
src/vs/workbench/contrib/accessibility/browser/accessibilityConfiguration.ts Added Survey verbosity setting
extensions/copilot/src/platform/survey/vscode/surveyServiceImpl.ts Replaced external URL with in-editor command

Moves in-product surveys from notification-based flows into an editor
pane, following the same pattern as the issue reporter editor.

- EditorInput + EditorPane architecture (singleton, readonly)
- Segmented control (Q1) styled with --vscode-radio-* tokens
- List-row selection (Q2/Q3) with native radios visually hidden inside
  full-width label elements, styled via :has(:checked)
- Responsive container query (collapses 2-col to 1-col at 600px)
- HC/focus-visible support for both segment and list-row patterns
- Success animation with auto-close after 3s
- Telemetry event for survey submission (survey/submit)
- Works in both workbench and sessions/agent window
- Testable via Developer: Open Survey command

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

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

Adds a proof-of-concept “in-editor” survey experience to the VS Code workbench (and Sessions window) by introducing a dedicated EditorInput + EditorPane pair, plus a developer command to open the survey and basic submission telemetry.

Changes:

  • Registers a new survey editor (SurveyEditorInput/SurveyEditorPane) and wires it into the workbench + sessions entrypoints.
  • Defines an initial Copilot PMF survey model (3 questions) and renders it with a segmented control + list-row radio selection.
  • Logs a survey/submit telemetry event and shows a success state with auto-close.
Show a summary per file
File Description
src/vs/workbench/workbench.web.main.ts Imports the surveys contribution for web workbench startup.
src/vs/workbench/workbench.desktop.main.ts Imports the surveys contribution for desktop workbench startup.
src/vs/workbench/contrib/surveys/browser/surveyQuestions.ts Adds the initial Copilot PMF survey definition + question types.
src/vs/workbench/contrib/surveys/browser/surveyEditorPane.ts Implements the editor pane UI, interaction handling, submit flow, and success state.
src/vs/workbench/contrib/surveys/browser/surveyEditorInput.ts Adds the singleton/readonly editor input and icon for survey editor.
src/vs/workbench/contrib/surveys/browser/survey.contribution.ts Registers the editor pane and a Developer command to open the survey.
src/vs/workbench/contrib/surveys/browser/media/surveyEditorPane.css Adds styles for the survey layout, segmented control, list rows, and success state.
src/vs/sessions/sessions.web.main.ts Imports the surveys contribution for sessions web startup.
src/vs/sessions/sessions.desktop.main.ts Imports the surveys contribution for sessions desktop startup.

Copilot's findings

  • Files reviewed: 9/9 changed files
  • Comments generated: 10

Comment thread src/vs/workbench/contrib/surveys/browser/survey.contribution.ts
Comment thread src/vs/workbench/contrib/surveys/browser/surveyQuestions.ts
Comment thread src/vs/workbench/contrib/surveys/browser/surveyEditorPane.ts
Comment thread src/vs/workbench/contrib/surveys/browser/surveyEditorPane.ts
Comment thread src/vs/workbench/contrib/surveys/browser/surveyEditorPane.ts Outdated
Comment thread src/vs/workbench/contrib/surveys/browser/media/surveyEditorPane.css
Comment thread src/vs/workbench/contrib/surveys/browser/media/surveyEditorPane.css
Comment thread src/vs/workbench/contrib/surveys/browser/media/surveyEditorPane.css
Comment thread src/vs/workbench/contrib/surveys/browser/media/surveyEditorPane.css
Comment thread src/vs/workbench/contrib/surveys/browser/surveyEditorPane.ts Outdated
digitarald and others added 2 commits June 19, 2026 19:10
- Gate 'Open Survey' command behind IsDevelopmentContext (dev builds only)
- Localize all user-facing strings (title, description, questions, options)
- Use stable option IDs for telemetry instead of locale-dependent labels
- Replace custom submit button CSS with shared Button widget
- Add aria-hidden on decorative icons (sparkle, checkAll)
- Add role=status + aria-live=polite on success container
- Announce 'Response sent' via status() for screen readers
- Move focus to success container after submit
- Use --vscode-strokeThickness token for border widths
- Snap padding to spacing ramp (7px → 8px)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Responsive:
- Remove broken flex-wrap on segment control (caused 2x2+1 orphan grid)
- At narrow widths, segment stacks vertically (flex-direction: column)
  with full-width items and proper border-radius per edge
- Segment labels get min-width: 0 + text-overflow: ellipsis so they
  shrink gracefully in horizontal mode without wrapping
- Remove overflow: hidden from segment group (was clipping focus rings)

Accessibility:
- Add role=form + aria-label on the editor pane container
- Increase auto-close timeout to 5s (gives screen readers time to read)
- Add position: relative on focus-visible segments for z-index stacking
- Segment labels get explicit border-radius on first/last (no overflow
  hidden needed)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
digitarald and others added 7 commits June 20, 2026 12:10
Engineering:
- Override focus() to move focus to first radio when survey opens
- Make resource URI dynamic (vscode-survey:/{surveyId}) to prevent
  collisions across multiple survey definitions
- Guard closeEditor in auto-close timeout with .catch(onUnexpectedError)

Accessibility:
- Add aria-required=true on all radio groups
- Fix HC focus-visible vs checked outline conflict: checked uses 1px
  solid contrastActiveBorder, focus-visible uses 2px dashed focusBorder
- Add completion hint ('Answer all questions to submit') with
  aria-describedby on the submit button; hides once all answered

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add position: relative to contain absolutely-positioned radio inputs,
and flex-wrap: nowrap to ensure 5 segment items always stay in a single
row at widths above the 600px container-query breakpoint.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Remove one-sided border-radius + left-accent on selected list rows;
  use full rectangular border matching VS Code's native list selection
- Reduce row padding (8px→6px), gap (4px→2px), question margin (24→20px)
  and submit margin (28→20px) for a more compact layout
- Add 60px bottom padding to ensure the Submit button is always reachable
  when scrolling
- Split container queries: segment stacks at 560px, list grid collapses
  to single-column at 480px (was 600px for both — too aggressive)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add SurveyAccessibilityHelp with AccessibleViewProviderId.Survey and
  AccessibilityVerbositySettingId.Survey for screen reader discovery
- Use var(--vscode-strokeThickness) for list-option border
- Use var(--vscode-codiconFontSize) + transform: scale(2) for success icon
- Reduce list-option padding to 6px 10px (on spacing ramp)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add 'source' field to SurveyEditorInput so the triggering feature
  (completions, panel.agent, agent.codeEdit) is captured with the response
- Register '_workbench.action.openCopilotSurvey' command for the Copilot
  extension to open the in-editor survey instead of external URL
- Restructure telemetry: extract pmfScore, primaryBenefit, primaryFriction
  as top-level fields for direct Kusto querying (keep JSON blob for
  forward-compat)
- Rename question IDs: main-benefit→primary-benefit, blockers→primary-friction
- Add pmfQuestionId to ISurveyDefinition schema

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- pmfScore is now a number (0=not at all, 4=extremely) with
  isMeasurement:true for direct Kusto aggregation - no JSON blob
- Update Copilot SurveyService.promptSurvey() to call
  '_workbench.action.openCopilotSurvey' command instead of opening
  external URL - works in both main workbench and agent window
- Remove unused IAuthenticationService, IEnvService, SURVEY_URI from
  SurveyService (no longer needed without external URL)

Co-authored-by: Copilot <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.

Copilot's findings

  • Files reviewed: 12/12 changed files
  • Comments generated: 3

Comment thread src/vs/workbench/contrib/surveys/browser/survey.contribution.ts
Comment thread src/vs/workbench/contrib/surveys/browser/surveyEditorPane.ts
Comment thread src/vs/workbench/contrib/surveys/browser/media/surveyEditorPane.css
digitarald and others added 3 commits June 21, 2026 10:23
- Validate command source against allowlist (telemetry safety)
- Add runtime guard for dev command in stable builds
- Make SurveyEditorInput.source mutable via updateSource()
- Update existing input's source when singleton is re-opened
- Restore focus to survey pane when closing a11y help
- Await command execution in extension with error handling

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Questions now declare their own telemetry field via telemetryKey and
asMeasurement properties. The pane iterates these at submit time
instead of hardcoding field names.

Telemetry fields:
- score (number): primary measure, option index
- primaryBenefit (string): value driver option ID
- primaryFriction (string): friction point option ID
- programmingExperience (number): experience bracket index

Added Q4: programming experience (5 brackets, 0-4 numeric measure).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@digitarald digitarald marked this pull request as ready for review June 21, 2026 22:50
@digitarald digitarald enabled auto-merge (squash) June 21, 2026 22:50
@digitarald digitarald changed the title Add in-editor PMF survey pane (POC) Add in-editor survey pane Jun 21, 2026
digitarald and others added 2 commits June 21, 2026 17:28
- Source allowlist now uses prefix matching (inline.*, panel.*, agent.*)
  to accept real Copilot sources like inline.codeEdit, panel.agent
- Extension resets cooldown to DAYS_LATER on command failure so users
  get re-prompted instead of losing 90 days silently
- Added 'Something else' escape hatch to Q2 (benefit) and Q3 (friction)
  so users are not forced into inaccurate answers

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Programming experience now renders as a segment band with compressed
  labels (<3 yr, 3-5 yr, 6-9 yr, 10-19 yr, 20+ yr) — saves vertical
  space and matches the PMF score visual pattern
- Increased container bottom padding from 60px to 80px to prevent
  submit button from being clipped when scrolled

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@digitarald digitarald merged commit 918dfc4 into main Jun 22, 2026
28 checks passed
@digitarald digitarald deleted the digitarald/in-editor-pmf-survey branch June 22, 2026 01:12
@vs-code-engineering vs-code-engineering Bot added this to the 1.126.0 milestone Jun 22, 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