Skip to content

Add external-link button to the Packages pane#14142

Open
bricestacey wants to merge 2 commits into
mainfrom
13890/packages-external-url-button
Open

Add external-link button to the Packages pane#14142
bricestacey wants to merge 2 commits into
mainfrom
13890/packages-external-url-button

Conversation

@bricestacey

@bricestacey bricestacey commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds an external-link button to each Packages pane row. When a package
advertises a website, the row shows a button (beside the help button) that
opens it in the user's external browser.

The URL comes from the language runtime via the existing getPackages call
-- no third-party API, so it works offline. A new optional url is added to
ILanguageRuntimePackage (and the public LanguageRuntimePackage). The
Python kernel picks the single best URL from a distribution's Project-URL
metadata (homepage > repository > documentation, with the legacy Home-page
header as a homepage fallback). The frontend validates the scheme (http/https
only) before rendering the button, so a malformed or non-web scheme from a
runtime can never reach the opener.

R support comes from a companion ark PR (posit-dev/ark#1261); the R button
lights up once that lands and the ark submodule is bumped in Positron.

See #13890

Screenshots

Screenshot 2026-06-09 at 5 15 22 PM Screenshot 2026-06-09 at 5 15 18 PM Screenshot 2026-06-09 at 5 15 10 PM Screenshot 2026-06-09 at 5 15 06 PM

Release Notes

New Features

Bug Fixes

  • N/A

Validation Steps

@:packages-pane

  1. Start a Python session and open the Packages pane.
  2. Filter to a package that publishes a homepage (e.g. numpy, pandas, requests).
  3. Confirm an external-link button appears beside the help button, and clicking it opens the package's website in your browser.
  4. Confirm a package with no URL metadata shows no link button.

Add an optional `url` to ILanguageRuntimePackage and the public
LanguageRuntimePackage. The Packages pane renders an external-link
button beside the help button when a package has a URL, validating the
scheme (http/https only) before opening it externally. The help and
link buttons share one icon-button style; the link glyph is nudged a
touch smaller for optical balance.

The Python kernel picks the single best URL per package from its
Project-URL metadata (homepage > repository > documentation, with the
legacy Home-page header as a homepage fallback) and returns it from
getPackagesInstalled, so pip, uv, and conda all surface it.

See #13890
@github-actions

github-actions Bot commented Jun 9, 2026

Copy link
Copy Markdown

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

readme  valid tags

@github-actions

github-actions Bot commented Jun 9, 2026

Copy link
Copy Markdown

PETE's assessment 🧪

Verdict: 🟢 Adequate -- the URL-selection logic carries thorough unit coverage and the new frontend button has e2e render coverage, matching the cheapest viable level for each change.

What changed

  • Python kernel learns to pick a single best package URL (_best_package_url in ui.py): ranks homepage > repository > documentation > other, with the legacy Home-page header as a homepage fallback; _get_packages_installed attaches the result as an optional url.
  • A new optional url is threaded through the public LanguageRuntimePackage (positron.d.ts) and internal ILanguageRuntimePackage (runtimeSessionService.ts).
  • The Packages pane (listPackages.tsx + .css) renders an external-link button per row, gated on matchesSomeScheme(url, http, https) so non-web schemes can't reach the opener.

Tests in this PR

  • Unit (Vitest/Mocha) ✅ (Python test_ui.py covers the URL-ranking logic; frontend gate is a thin wrapper over a core util -- see below)
  • Extension host ✅ (not applicable -- no activated-extension behavior changed)
  • E2E (Playwright) ✅ (added to packages-pane.test.ts, new urlButton page-object locator)

Existing coverage

  • extensions/positron-python/.../tests/test_ui.py adds test_best_package_url with 8 parametrized cases pinning the exact ranking contract (homepage-beats-repository, normalized labels, legacy Home-page, project-url-beats-legacy, unrecognized-fallback, and the None case). This is the substantive new logic and it's well covered at the cheapest level.
  • test/e2e/tests/packages-pane/packages-pane.test.ts adds a URL button test asserting the link button is visible for numpy (which publishes a homepage), exercising the full kernel -> url field -> scheme-gate -> rendered button path. Reasonable to verify at e2e since it spans the runtime + workbench render.
  • The frontend hasValidUrl gate is a single call to the already-tested core matchesSomeScheme; the ListPackages component has no existing vitest harness, so a dedicated unit test would be low-value relative to setup cost. The e2e covers the positive render.

Suggested additions

None. Optionally, the no-URL negative branch ("a package with no URL shows no button," per the PR's own validation steps) is asserted only on the Python side (_best_package_url -> None), not in the e2e; adding a toHaveCount(0) assertion for a URL-less package would round out the frontend gate, but the existing coverage is sufficient.

Deployment note (optional)

The new e2e test is tagged @:web (via the suite-level tags.WEB), so the link button renders in the web build too -- good, since openerService.open(..., { openExternal: true }) behaves differently across desktop and web. No Windows-specific concern here (the change touches no path/process/pty hotspots).


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.

`PackageMetadata` (the 3.14 typing protocol) doesn't expose `.get()`, and
`_URL_CATEGORY_PRIORITY.get(category, ...)` was handed a `str | None` key.
Route metadata access through an `Any`-typed local (as
_get_packages_installed already does) and index the priority map only for
recognized categories.

See #13890
@bricestacey bricestacey marked this pull request as ready for review June 10, 2026 14:17
@austin3dickey austin3dickey self-requested a review June 10, 2026 15:06

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

This looks awesome, Brice! It's so cool to see this pane's progress.

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.

2 participants