Skip to content

feat(ssh): pre-check the Remote SSH extension before starting the tunnel - #2168

Draft
anton-107 wants to merge 1 commit into
mainfrom
feat/ssh-remote-extension-precheck
Draft

feat(ssh): pre-check the Remote SSH extension before starting the tunnel#2168
anton-107 wants to merge 1 commit into
mainfrom
feat/ssh-remote-extension-precheck

Conversation

@anton-107

Copy link
Copy Markdown
Contributor

Changes

databricks ssh connect needs the host editor's Remote SSH extension to open the
remote window, and checks for it by shelling out to <command> --list-extensions
from inside the terminal. Check the running editor's own extension registry
instead, before the terminal exists, and offer a button that installs through the
editor's marketplace client.

  • HostUtils.getHostSshExtension() resolves the extension id, display name and
    minimum version per host, mirroring the CLI's IDE descriptors the way
    getHostCliCommand already mirrors its --ide handling.
  • HostUtils.getSshExtensionStatus() returns ok / missing / outdated from
    extensions.getExtension, treating an unparseable version as too old exactly as
    the CLI does.
  • SshCommands.offerToInstallSshExtension() prompts, then runs
    workbench.extensions.installExtension.

Unlike the host-CLI PATH warning beside it, this awaits the user's choice rather
than firing and forgetting: installing takes a moment, and the point is to let the
attempt the user just started succeed rather than fail and depend on a retry. It
still never gates the tunnel — a dismissed or failed install falls through to the
CLI's own check, which reports the real error.

Why

The CLI-side extension check is the largest single source of failed IDE-mode
tunnels in telemetry, and its failures are sticky: of the users whose first
attempt hit it, only about an eighth ever established a tunnel, despite averaging
2.7 attempts. It is heavily Windows-skewed, and it is also why Cursor users fail
less often than VS Code users — Cursor ships a Remote SSH equivalent, while VS
Code needs a marketplace install.

Reading the editor's registry cannot fail the way spawning a process can, so this
removes the list-failure path rather than working around it. The extension already
passes --auto-approve, so today these users are never prompted at all: the CLI
goes straight to an auto-install that fails inside a terminal they did not ask
for. This is the same shape as the existing host-CLI PATH pre-check, applied to
the bigger cause.

Companion CLI change, which splits the single telemetry category behind this into
four so the remaining failures are attributable: databricks/cli#6497.

Tests

Not yet compiled or tested — please treat as unverified. The npm registry does
not resolve from the environment this was written in, so yarn install fails and
there is no node_modules to typecheck or run Mocha against. This needs a
yarn test run on a machine with registry access before it should be trusted or
merged. That is the main reason this is a draft.

What was verified without a toolchain:

  • All four touched files parse under Node's type stripper.
  • Added lines sit within Prettier's 80 columns, and follow the repo's 4-space,
    double-quote, bracketSpacing: false settings.
  • Import order matches the convention (external packages before local relative
    imports).
  • Narrowing is done on status.kind directly rather than through an aliased
    boolean, so nothing depends on inference I could not check.

Tests written but not executed — 11 cases across two files:

  • hostUtils.test.ts: per-host extension id, missing / at-minimum / above-minimum
    / below-minimum / unparseable version, and that the Cursor floor applies in
    Cursor.
  • SshCommands.test.ts: silent when usable, offers Install when missing, offers
    Update naming the installed version, installs nothing when dismissed, and does
    not throw when the install itself fails.

One thing worth a reviewer's attention: hostUtils.ts now imports semver, which
is not a declared dependency — only @types/semver is in devDependencies.
src/whatsNewPopup.ts already relies on the same hoisted package in shipped code,
so I followed that precedent, but adding it to dependencies may be the right
call and I could not relock without registry access.

This pull request and its description were written by Isaac.


This PR was created with GitHub MCP.

`databricks ssh connect` needs the host editor's Remote SSH extension to open
the remote window, and checks for it by shelling out to
`<command> --list-extensions` from inside the terminal. That check is the
largest single source of failed IDE-mode tunnels, and its failures are sticky:
most users who hit it never get a working tunnel, even across several attempts.

Check the running editor's own extension registry instead, before the terminal
exists, and offer a button that installs through the editor's marketplace
client. Reading the registry cannot fail the way spawning a process can, so this
removes the list-failure path rather than working around it.

Unlike the host-CLI PATH warning next to it, this awaits the user's choice:
installing takes a moment, and the point is to let the attempt they just started
succeed rather than fail and depend on a retry. It still never gates the tunnel
-- a dismissed or failed install falls through to the CLI's own check, which
reports the real error.

Adds HostUtils.getHostSshExtension/getSshExtensionStatus, mirroring the CLI's IDE
descriptors the way getHostCliCommand already mirrors its --ide handling.

Co-authored-by: Isaac <no-reply@databricks.com>
@anton-107
anton-107 deployed to test-trigger-is September 2, 2026 19:13 — with GitHub Actions Active
@anton-107
anton-107 deployed to test-trigger-is September 2, 2026 19:13 — with GitHub Actions Active
@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

If integration tests don't run automatically, an authorized user can run them manually by following the instructions below:

Trigger:
go/deco-tests-run/vscode

Inputs:

  • PR number: 2168
  • Commit SHA: 446109795539b3bb9cb6a0b260c60a3ec6d49a39

Checks will be approved automatically on success.

@anton-107
anton-107 deployed to test-trigger-is September 2, 2026 19:14 — with GitHub Actions Active
@rugpanov

rugpanov commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

🤖 Integration tests ❌ 1 of 41 test jobs failed for 44610979 (40 passed).
View run

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants