Skip to content

feat: install jgd into a vscode-R-managed tool library on demand - #1907

Merged
eitsupi merged 21 commits into
REditorSupport:mainfrom
eitsupi:feat/managed-tool-library
Oct 25, 2026
Merged

eitsupi merged 21 commits into
REditorSupport:mainfrom
eitsupi:feat/managed-tool-library

Conversation

@eitsupi

@eitsupi eitsupi commented Oct 25, 2026 •

Copy link
Copy Markdown
Member

As suggested in #1856, packages that vscode-R needs as tools, rather than as project dependencies, should not have to live in user or project libraries. This applies especially to jgd, which has no R package dependencies. This PR lets ordinary R terminals and manual session attachment offer to install jgd into a vscode-R-managed tool library when the JGD plot viewer is available. Libraries owned by renv, pixi, conda, or the user are not modified.

Tool library

Unlike sess, jgd is a CRAN package that cannot be pinned to the extension's source revision, and it has no dependency tree to isolate. The tool library is therefore deliberately simpler than the managed sess library. sess installation is unchanged.

  • Layout. One library per R platform and major.minor version (<globalStorage>/packages/<platform>/<major.minor>/library), following the convention of R_LIBS_USER. Only the most recently installed version of each package is kept.
  • Allowed packages. Only packages on a fixed allowlist (currently jgd) can be installed, from the repositories configured in the R session. A version that declares non-base Depends, Imports, or LinkingTo is refused before installation. Packages are installed with dependencies = FALSE.
  • Selection. A compatible namespace that is already loaded is used as is. Otherwise, a compatible copy in the normal libraries is preferred, then the tool library copy, which is loaded with loadNamespace(lib.loc = ). .libPaths() is never changed.
  • Installation. Installation is serialized by a per-library directory lock, with the same rules as the managed sess setup, and verified in a child R process. A package is reinstalled only when it no longer satisfies the required minimum version (jgd 0.1.0); there is no automatic update.
  • Known limitation. Updating a copy that another R process has loaded can fail on Windows, or affect that process on Unix, as with an ordinary install.packages(). The error message asks the user to close other R sessions and retry.

Consent

The file-based consent transport used for sess is shared with a new package consent request (vscode-r-package-consent-v1). The request carries the resolved version, repository, package type, and whether a source build may be required. Approval applies only to that exact plan. The sess request format and behavior are unchanged.

  • With r.plot.backend set to "jgd", installation is offered whenever setup requires it.
  • With "auto", the offer appears at most once per VS Code window session. Not now or dismissal postpones it to a later window session. Don't ask again is remembered in the extension's global state for the current minimum jgd version, like the sess prompt for each bundled revision, so raising the minimum version offers installation again. Selecting "jgd" still offers installation.
  • When no offer can be shown, R uses an existing compatible copy or falls back without querying repositories, so terminal startup is not slowed down.

Terminal and attach integration

Before sess::connect(), the startup profile and manual attach prepare and load jgd when the plot backend is jgd or auto, and pass the result to the new allow_jgd argument of sess::connect(). When it is FALSE, sess does not select jgd, does not take the JGD socket from the discovery file, and keeps that decision for automatic reconnects. This prevents an incompatible jgd that is already loaded or installed in a normal library from being used. The bundled sess development version is bumped to 3.2.9000.9000.

R waits for the decision with the same limits as the sess setup (consent 180 s, lock 300 s), and code sent during setup stays queued. Each repository metadata request uses a download timeout of at most 30 s. Declining, failures, offline repositories, or an incompatible loaded jgd fall back to httpgd or the standard viewer, without blocking the terminal or the session watcher.

Experimental R Interactive is not changed.

@eitsupi
eitsupi marked this pull request as ready for review October 25, 2026 03:46
@eitsupi
eitsupi requested a review from renkun-ken October 25, 2026 03:46

@renkun-ken renkun-ken left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed head 181a1236711e34827205c142cecfb60b9252010d. Two reproduced issues are detailed inline: the rejected-jgd fallback is overridden by sess discovery, and the preparation test inherits installed user packages.

Local validation passed for compilation/type checking, all 19 focused tool/sess consent Node tests, the R tool library and consent tests, sess identity/attach tests, and all six source/packaging tests. The R preparation suite passes with isolated R_LIBS_USER/R_LIBS_SITE, but fails with an ordinary installed jgd 0.2.1. All six current CI checks are green.

Comment thread R/prepare-jgd.R Outdated
Comment thread R/tests/prepare-jgd.R Outdated
@eitsupi
eitsupi requested a review from renkun-ken October 25, 2026 07:30
The preparation tests now drive real sess connections and need the sess dependencies installed by the build step.
@eitsupi

eitsupi commented Oct 25, 2026 •

Copy link
Copy Markdown
Member Author

@renkun-ken Thanks for your review. I've adressed your points.

@renkun-ken renkun-ken left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-reviewed head 7872c96a078f2bce1fa0be12e4db01a3ee082abe. Both previous findings are addressed: allow_jgd gates discovery socket updates and runtime selection and is retained for automatic reconnects; the preparation tests isolate their R children, including the startup-profile child. The new real IPC tests cover incompatible loaded/user copies and approved managed installation across reconnects. I found no further actionable issues in the update.

Validation: the preparation suite passes with jgd 0.2.1 installed in my normal user library; all 1,265 sess test results and 19 focused tool/sess consent Node tests pass. Compilation/type checking, R tool library/consent tests, sess attach/identity tests, six source/packaging tests, and git diff --check also pass. All six CI checks are green.

@eitsupi
eitsupi merged commit 929a9e9 into REditorSupport:main Oct 25, 2026
6 checks passed
eitsupi added a commit that referenced this pull request Oct 26, 2026
As a step towards #1859, this PR removes the rstudioapi package from the R package dependencies of sess. Like jgd in #1907, vscode-R now offers to install it into the vscode-R-managed tool library when RStudio API emulation needs it. User and project libraries are not modified.

## Why rstudioapi is still needed

sess only calls `rstudioapi::` inside the emulated functions, which it patches into the rstudioapi namespace when rstudioapi is loaded. sess itself therefore works without it. However, because the managed sess library currently installs and loads rstudioapi, packages that check `requireNamespace("rstudioapi")` (for example usethis) and console calls such as `rstudioapi::navigateToFile()` reach the emulation even in isolated libraries such as renv projects. To keep this behavior, vscode-R prepares rstudioapi before `sess::connect()` and loads it eagerly.

rstudioapi has no `Depends`, `Imports`, or `LinkingTo` in any CRAN release and needs no compilation, so it meets the tool library requirements. The minimum version is 0.4.0, the first release that exports all the document position and range helpers used by the emulation.

## Behavior

- sess lists rstudioapi in `Suggests` instead of `Imports`, and the managed sess installation no longer installs or preloads it.
- When `r.session.emulateRStudioAPI` is enabled, terminal startup and manual attach use a compatible rstudioapi that is already loaded or in the normal libraries, then the tool library copy. Otherwise, they offer installation.
- The offer appears at most once per VS Code window session. **Don't ask again** is remembered for the current minimum version, as with jgd and the `"auto"` plot backend.
- Declining, failures, or offline repositories print one short message. Emulation stays enabled and applies whenever rstudioapi is loaded later. A loaded rstudioapi is never replaced.
- When no offer can be shown, R uses an existing compatible copy without querying repositories. When emulation is disabled, nothing is prepared.

## Consent

Package consent requests now carry a prompt policy (`always` or `once`) instead of the plot backend, and the prompt state and **Don't ask again** are tracked per package. A jgd and an rstudioapi request in the same startup are therefore independent. The behavior of jgd is unchanged, including its stored **Don't ask again** choice. Minimum versions of tool packages are defined in one place and passed to R.

The jgd preparation helper is generalized and renamed to `R/prepare-tools.R`.

Experimental R Interactive still installs rstudioapi for its private runtime and is otherwise unchanged.
@eitsupi
eitsupi deleted the feat/managed-tool-library branch October 26, 2026 14:14
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