Skip to content

Highlight newly installed or updated packages in the Packages pane#14284

Merged
bricestacey merged 4 commits into
mainfrom
13129/highlight-installed-package
Jun 24, 2026
Merged

Highlight newly installed or updated packages in the Packages pane#14284
bricestacey merged 4 commits into
mainfrom
13129/highlight-installed-package

Conversation

@bricestacey

@bricestacey bricestacey commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

Fixes #13129

Summary

After installing or updating a package in the Packages pane, the affected package(s) now scroll into view and briefly flash so the change is easy to spot in a long list.

  • Install and single update select, scroll to, and flash the requested package. Dependencies the package manager pulls in are excluded; only the package you asked for is highlighted.
  • Update All flashes every package whose version actually changed (diffed against a pre-update snapshot) and scrolls to the first one.
  • A package hidden by an active filter is skipped rather than revealing it.

A new onDidChangePackages event on the packages instance reports the affected names after a successful operation; the view scrolls/selects/flashes them via a transient recently-changed CSS animation (which respects prefers-reduced-motion). The flash is gated on a nonce, and its clear timer lives in a dedicated effect, so the asynchronous Stage 2 metadata refresh cannot re-trigger or cancel the flash mid-animation.

Screenshots

Screen.Recording.2026-06-15.at.1.42.17.PM.mov

Release Notes

New Features

Bug Fixes

  • N/A

Validation Steps

@:packages-pane

  1. Open the Packages pane with a runtime (R or Python) that has a long package list.
  2. Install a package not currently installed and verify the new row scrolls into view, is selected, and briefly flashes.
  3. Update a single outdated package and verify its row flashes.
  4. Run Update All and verify every package whose version changed flashes, scrolling to the first.
  5. Type a filter that excludes the package you install, then install it; verify the list does not jump or clear the filter.

After an install or update completes, scroll to and briefly flash the
affected package(s) so the change is easy to spot in a long list.

- Install and single update select, scroll to, and flash the requested
  package (auto-installed dependencies are excluded).
- Update All flashes every package whose version actually changed,
  diffed against a pre-update snapshot, and scrolls to the first.
- Packages hidden by an active filter are skipped rather than revealed.

A new onDidChangePackages event on the packages instance reports the
affected names; the view scrolls/selects/flashes them via a transient
'recently-changed' CSS animation. The flash is gated on a nonce and its
clear timer lives in a dedicated effect so the asynchronous Stage 2
metadata refresh cannot re-trigger or cancel it mid-flash.

See #13129
@github-actions

github-actions Bot commented Jun 15, 2026

Copy link
Copy Markdown

E2E Tests 🚀
This PR will run tests tagged with: @:critical @:packages-pane

readme  valid tags

@github-actions

Copy link
Copy Markdown

PETE's assessment 🧪

Verdict: 🔴 Insufficient -- the instance-side event is well covered, but the new scroll/select/flash logic in listPackages.tsx (the heart of this feature) has no test at any level.

What changed

  • positronPackagesInstance.ts: a new onDidChangePackages event fired after install (requested names), update (requested names), and update-all (only packages whose version changed, diffed against a pre-update snapshot).
  • listPackages.tsx: consumes the event to scroll to, select, and flash affected rows -- with non-trivial branches: skip packages filtered out of view, select only on a single-package op (not bulk), and a nonce + dedicated clear-timer effect so the async Stage 2 refresh can't re-trigger or cancel the flash.
  • listPackages.css: a transient recently-changed flash animation that degrades to a steady tint under prefers-reduced-motion.

Tests in this PR

  • Unit (Vitest/Mocha) ✅ (added 3 it(...) blocks in positronPackagesInstance.vitest.ts)
  • Extension host ✅ (not applicable)
  • E2E (Playwright) ✅ (not applicable -- view logic is unit-testable; see below)

Existing coverage

  • positronPackagesInstance.vitest.ts (the 3 new cases) fully covers the event side: requested-names on install/update, and the version-diff filter on update-all (numpy changed, pandas unchanged -> only ['numpy']). Solid.
  • test/e2e/tests/packages-pane/packages-pane.test.ts exercises install/search/uninstall but asserts nothing about scroll, selection, or the flash -- it does not cover this PR's behavior.
  • No test (vitest .tsx or otherwise) imports or renders ListPackages. The view-side branches are entirely unexercised.

Suggested additions

  • Add src/vs/workbench/contrib/positronPackages/test/browser/listPackages.vitest.tsx: an RTL service-context component test (the pattern used by positronList.vitest.tsx and the other .vitest.tsx files in this contrib tree -- unit suffices, no e2e needed). Cover the consumer logic that has real failure modes:
    • Filtered-out skip (listPackages.tsx:275-281): firing onDidChangePackages for a name absent from filteredPackages produces no scroll/select and no flash -- the "don't reveal a filtered package" guarantee from the PR description.
    • Single vs bulk select (listPackages.tsx:286-288): one name -> selectRow called for that row; multiple names -> scrollToRow to the min index but selectRow not called.
    • Nonce gating (listPackages.tsx:270-273): a second filteredPackages settle (the Stage 2 refresh) with the same highlight nonce does not re-apply the flash; a new event (new nonce) does.
    • Flash lifecycle (listPackages.tsx:296-302): the recently-changed class is applied to affected rows and cleared after the timer, and the Stage 2 re-run does not cancel it mid-flash.

Suggested tags (optional)

None -- the PR body already includes @:packages-pane, which matches the existing e2e suite for this area.


PETE (Positron Extreme Test Experiment) - LLM-based test-coverage advisor, in pilot. Triggers on PR open and on /recheck-tests comments. Wrong verdict? Comment /recheck-tests (or /rePETE) on this PR to re-run. Please share feedback on how PETE performed here.

Add an RTL component test for the onDidChangePackages consumer in
ListPackages, the heart of the highlight feature that the instance-side
tests don't reach:

- single install/update flashes, selects, and pushes the service-level
  selection for the requested package
- a bulk update flashes every affected row but selects none
- a package hidden by the active filter is neither revealed nor flashed
- the flash survives the async Stage 2 refresh and clears on schedule
- a later refresh does not revive a cleared flash (nonce gating)

See #13129
@bricestacey
bricestacey requested a review from softwarenerd June 23, 2026 17:48

@softwarenerd softwarenerd 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.

I tested this PR out and it appears to work well, with one exception. I added and removed cowsay multiple times. In each case, the package was scrolled into view, as see here:

Image

But I did not see anything resembling a "brief flash". Here's a screen recording of what I saw:

Screen.Recording.2026-06-23.at.4.56.10.PM.mov

When I scrolled through this screen recording frame-by-frame, I expected to see the UI scroll to cowsay first, then the "brief flash".

The flash reused editor.findMatchHighlightBackground, which is identical
to list.activeSelectionBackground in some themes (e.g. Light 2026), so
the flash was invisible on a just-selected row, and it borrowed a color
from an unrelated component.

Register positronPackages.recentlyChangedBackground, derived from the
selection background with a brightness offset (lighter in dark themes,
darker in light themes) so the transient flash always reads as distinct
from the selected row. Theme authors can override it.

See #13129
The previous derivation used lighten(selection): lighten is multiplicative
on HSL lightness (l + l*factor), so it cannot lift a pure-black base such as
the high-contrast dark selection background, producing no visible flash (and
the same brittleness near white).

Use a translucent foreground tint instead. The foreground contrasts the
background in every theme by definition, so the alpha overlay always shifts
the surface, including a selected row, keeping the flash distinct from the
selection color.

See #13129
@bricestacey

bricestacey commented Jun 24, 2026

Copy link
Copy Markdown
Contributor Author

But I did not see anything resembling a "brief flash". Here's a screen recording of what I saw:

From the looks of it you're using Light 2026, which has identical backgrounds for the theme colors I am using... Dark 2026, Dark, and Light don't have this issue.

"editor.findMatchHighlightBackground": "#0069cc1a",
"list.activeSelectionBackground": "#0069cc1a",

I've pushed up a fix. We register a new theme color for the packages pane positronPackages.recentlyChangedBackground.

At first, I tried to lighten or darken the existing active selection background. This seemed fine, but starts to perform poorly the darker the color before eventually having no effect at all for pure black.

The solution we wound up on is to make the recently changed background color equal to 25% of the foreground color. This is guaranteed to have an effect since the foreground and background by definition should be contrasting colors.

Here is an example using Light 2026.

Screen.Recording.2026-06-23.at.11.10.11.PM.mov

One drawback is this will naturally be relatively... boring? It's not the traditional yellow highlighter, but I think this is a good solution.

@softwarenerd softwarenerd 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.

LG now.

@bricestacey
bricestacey merged commit b45bc04 into main Jun 24, 2026
28 checks passed
@bricestacey
bricestacey deleted the 13129/highlight-installed-package branch June 24, 2026 23:07
@github-actions github-actions Bot locked and limited conversation to collaborators Jun 24, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Highlight newly installed package or updated package in the packages pane

2 participants