Skip to content

Remote-SSH/WSL/Codespaces transport + CI & smoke tests - #8

Merged
ofurkancoban merged 11 commits into
mainfrom
feat/remote-ssh-transport-ci
Jul 2, 2026
Merged

Remote-SSH/WSL/Codespaces transport + CI & smoke tests#8
ofurkancoban merged 11 commits into
mainfrom
feat/remote-ssh-transport-ci

Conversation

@ofurkancoban

Copy link
Copy Markdown
Owner

What

Fixes the last open issue (#5) and adds automated testing.

Remote transport (#5)

The webview always runs in the local UI, but with Remote-SSH / WSL / Dev Containers / Codespaces the R WebSocket server and its port live on the remote host, so the old ws://127.0.0.1:PORT never reached it (extension stayed Offline).

  • extension.ts now resolves every backend port through vscode.env.asExternalUri() and sends the forwarded wsUrl to the webview.
  • webview/main.js dials that wsUrl when present, falling back to ws://127.0.0.1:PORT on local sessions (no behavior change locally).
  • The R server already binds 127.0.0.1, which VS Code forwards.

CI + smoke tests

  • @vscode/test-cli smoke suite (src/test/extension.test.ts):
    • extension activates on a clean VS Code, with REditorSupport.r auto-installed (regression guard for command 'rPlotViewer.showPlot' not found #4),
    • all contributed commands are registered,
    • Julia is not a hard dependency.
  • GitHub Actions (.github/workflows/ci.yml): type-check + integration tests on Linux/macOS/Windows, plus a vsce package job uploading the VSIX.
  • .vscodeignore keeps the packaged VSIX lean (20 files, 640 KB).

Testing

  • npm test locally on macOS: 3 passing (VS Code 1.127.0 downloaded, reditorsupport.r-2.8.8 installed, extension activated).
  • npm run compile: clean.
  • vsce package: clean, 20 files / 640 KB.

- Resolve backend loopback ports via vscode.env.asExternalUri so the webview
  reaches the R WebSocket server when it runs on a remote host (fixes #5).
  Webview now dials the forwarded wsUrl, falling back to ws://127.0.0.1:PORT
  on local sessions.
- Add @vscode/test-cli smoke tests: extension activates on a clean VS Code
  (regression guard for #4), all contributed commands register, and Julia is
  not a hard dependency.
- Add GitHub Actions CI: type-check + integration tests on Linux/macOS/Windows
  and a package (vsce) job that uploads the built VSIX.
- Add .vscodeignore so the packaged VSIX stays lean (20 files, 640 KB).
- Export presets: the export QuickPick now offers PNG Screen (1x), High DPI
  (2x), Publication (3x ~300dpi), Slide 16:9 (1920x1080) and SVG. The webview
  rasterizes at the chosen scale, or fits+letterboxes into fixed dimensions.
  Split view honours the preset scale too.
- Favorites/notes now persist to the extension workspaceState (rplot.meta) and
  are restored by plot id on load, so they survive VS Code restarts even when
  the webview state is dropped. Falls back to the existing webview state.
- Gallery archive: plot images + metadata are snapshotted to global storage
  (archive-<configId>.json) and restored on load, so the gallery survives an
  R-session shutdown or VS Code restart. Archived plots use a sentinel port so
  a live plot with the same id always supersedes them; capped to 60 plots.
- PDF export: new PDF presets (Publication 3x, Slide 16:9) embed the rendered
  raster in a single-page PDF via a vendored, offline jsPDF (no runtime dep).
- Fix: CSP connect-src only allowed ws://localhost|127.0.0.1, which would block
  the Remote-SSH/Codespaces wss:// tunnels added for #5. Now allows ws:/wss:.
…uctured logging

- Sentinel is now activity-driven: it polls terminals only for a short window
  after a terminal opens/switches, then stops, dropping idle CPU to zero while
  still catching delayed R starts. Replaces the permanent 4s interval.
- Configurable port range: rPlotViewer.minPort/maxPort are passed to the R
  server via env vars so users behind strict firewalls can pin the range.
- Single-source version: scripts/sync-version.js propagates package.json version
  to init.R, plot_server.R and the README badge; runs in vscode:prepublish so a
  build can never ship a stale version. Bumped to 0.48.0.
- Structured logging: one Output channel + ring buffer; webview log/info now
  route there. New 'R Plot Pro: Report Issue' command opens a prefilled GitHub
  issue with environment info and the recent log.
Widen the scan window to 120s and re-open it on onDidChangeTerminalState
(shell-integration/interaction), so a user who opens a terminal, waits, then
manually starts R is still auto-attached. Idle CPU stays zero once the window
elapses. Does not affect live console connections (kept alive by the WebSocket
heartbeat and reconnect logic, independent of the sentinel).
…ct/merge modules

Start the webview TypeScript migration with a strangler-fig step so the riskiest
logic gains types and tests without rewriting the 2600-line DOM code (which is
coupled to inline HTML handlers and needs live testing to bundle wholesale).

- New TS modules under webview/src: ReconnectManager (reconnect state machine,
  linear backoff + sticky give-up, dependency-injected timers) and mergePlotLists
  (multi-terminal + archive-aware gallery merge). Fully typed and pure.
- esbuild bundles them to webview/vendor/rplot-core.js (IIFE global RPlotCore);
  main.js now delegates to it, replacing the inline duplicated logic.
- Unit tests (node/mocha, 14 cases) cover backoff, sticky give-up, clear/reset,
  active-before-fire, and every merge/dedup branch. New 'test:unit' script + CI step.
- Build wiring: compile now runs tsc + build:webview; tsconfig scoped to src;
  tsconfig.webview.json for the core modules.
Add a code button to the left of the favorite icon on each plot thumbnail with a
dropdown: Copy Code, Reveal Code in Console, Run Code Again, Open Source File.

- R server captures the top-level expression that produced each plot from the
  task callback (deparse + srcref) and attaches code/srcFile/srcLine1/srcLine2 to
  the plot metadata; carried through get_plots, the archive and restore.
- Webview renders the dropdown (viewport-clamped, items disabled when the plot has
  no captured code/file) and routes actions to the extension.
- Extension: Copy Code (clipboard, in webview), Reveal (type into the R terminal
  without running), Run Code Again (execute in the R terminal), Open Source File
  (open + select the captured line range). R terminal auto-detected.
The code (</>)  menu now lives in the toolbar next to Copy/Save and acts on the
currently selected plot (enabled with the other single-plot actions, disabled in
split view). Removed the per-thumbnail code button.
Lets users attach a pre-existing terminal (or one whose name is not detected as R)
that the sentinel misses - e.g. R already running in a zsh/bash terminal when the
extension activates. Focuses + force-injects the active terminal, with a clear
message when there is none. Smoke test now asserts the command is registered.
…nch detection

More reliable attach than name-based sentinel polling:

- Julia startup hook: offer a ~/.julia/config/startup.jl hook (mirrors the R
  .Rprofile hook) so Julia auto-captures at startup with no timing gap. Offered
  lazily the first time Julia is used; removable via a new command.
- Shell-integration detection: when VS Code reports a shell command, detect an
  interactive R/Julia launch by the actual command (not the terminal name) and
  inject on the clean starting prompt - catches R/Julia in generically-named
  shells and avoids corrupting a typed line. Feature-detected with sentinel
  fallback.
- Unify R/Julia hook add/remove into pure, tested helpers; fix a latent regex
  bug (unescaped '[' in markers) that made hook removal silently no-op.
- Guard Julia start_plot_viewer against double-start (hook + sentinel).

Tests: 31 integration+logic (detectLaunchLanguage + hook helpers, incl. false
positives like rm/rsync/ruby/Rscript), 14 unit; R + Julia parse clean.
@ofurkancoban
ofurkancoban marked this pull request as ready for review July 2, 2026 13:59
@ofurkancoban
ofurkancoban merged commit 52c248a into main Jul 2, 2026
4 checks passed
@ofurkancoban
ofurkancoban deleted the feat/remote-ssh-transport-ci branch July 2, 2026 14:07
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.

1 participant