Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 57 additions & 0 deletions apps/web/src/remoteOpen.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {
BearerConnectionTarget,
PrimaryConnectionTarget,
RelayConnectionTarget,
SshConnectionTarget,
Expand Down Expand Up @@ -129,6 +130,62 @@ describe("resolveRemoteOpenState", () => {
).toBe("cursor://vscode-remote/ssh-remote+admin-user%40server.tail1234.ts.net/work/project");
});

it("opens the client host environment's editor locally over a bearer target", () => {
expect(
resolveRemoteOpenState({
target: new BearerConnectionTarget({
environmentId,
label: "sol",
connectionId: "service-1",
}),
sshTarget: null,
isDesktopRenderer: true,
remoteOpenTargets: [],
isClientHostEnvironment: true,
}),
).toEqual({ mode: "local-exec" });
});

it("keeps reporting unavailable for a non-host bearer target", () => {
expect(
resolveRemoteOpenState({
target: new BearerConnectionTarget({
environmentId,
label: "sol",
connectionId: "service-1",
}),
sshTarget: null,
isDesktopRenderer: true,
remoteOpenTargets: [],
isClientHostEnvironment: false,
}),
).toEqual({ mode: "remote-unavailable" });
});

it("prefers local exec for the client host environment even when an SSH route exists", () => {
expect(
resolveRemoteOpenState({
target: new SshConnectionTarget({ environmentId, label: "sol", connectionId: "ssh-1" }),
sshTarget: { alias: "sol", username: null },
isDesktopRenderer: true,
remoteOpenTargets: TAILSCALE_TARGETS,
isClientHostEnvironment: true,
}),
).toEqual({ mode: "local-exec" });
});

it("still uses deep links for an SSH environment that is not the client host", () => {
expect(
resolveRemoteOpenState({
target: new SshConnectionTarget({ environmentId, label: "sol", connectionId: "ssh-1" }),
sshTarget: { alias: "sol", username: null },
isDesktopRenderer: true,
remoteOpenTargets: TAILSCALE_TARGETS,
isClientHostEnvironment: false,
}),
).toEqual({ mode: "remote-links", host: { kind: "ssh-alias", host: "sol" } });
});

it("reports unavailable when a remote environment advertises no hosts", () => {
for (const remoteOpenTargets of [[], undefined] as const) {
expect(
Expand Down
12 changes: 12 additions & 0 deletions apps/web/src/remoteOpen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ import { useAtomValue } from "@effect/atom-react";
import { isDesktopLocalConnectionTarget } from "~/connection/desktopLocal";
import { isLoopbackHostname } from "~/environments/primary/target";
import { useLocalStorage } from "~/hooks/useLocalStorage";
import { isClientHostEnvironment } from "~/state/clientHostEnvironment";
import { environmentPresentations } from "~/state/presentation";
import { hostEnvironmentIdAtom } from "~/state/primaryEnvironment";

export interface RemoteOpenHost {
readonly kind: "ssh-alias" | RemoteOpenTarget["kind"];
Expand Down Expand Up @@ -53,11 +55,15 @@ export function resolveRemoteOpenState(input: {
readonly sshTarget: { readonly alias: string; readonly username: string | null } | null;
readonly remoteOpenTargets: ReadonlyArray<RemoteOpenTarget> | undefined;
readonly isDesktopRenderer: boolean;
readonly isClientHostEnvironment?: boolean;
}): RemoteOpenState {
const { target } = input;
if (target === null) {
return LOCAL_EXEC;
}
if (input.isClientHostEnvironment === true) {
return LOCAL_EXEC;
}
if (target._tag === "PrimaryConnectionTarget") {
// Desktop owns its primary even at a non-loopback WSL2 NAT address.
if (input.isDesktopRenderer) {
Expand Down Expand Up @@ -120,6 +126,12 @@ const remoteOpenResolutionAtom = Atom.family((environmentId: EnvironmentId) =>
profile !== null && profile._tag === "SshConnectionProfile" ? profile.target : null,
remoteOpenTargets: presentation?.serverConfig?.remoteOpenTargets,
isDesktopRenderer: window.desktopBridge !== undefined,
isClientHostEnvironment: isClientHostEnvironment(
environmentId,
get(hostEnvironmentIdAtom),
entry.target,
window.desktopBridge !== undefined,
),
}),
isResolved: true,
};
Expand Down
Loading