tunnelAgentHostService.ts ×14

Frontier kind: Code frontier

unlabeled · c_96e9765add12

4 tests · 10317 LOC · 55 files · introduces 0 tests · 343 LOC · 2 files

Introduces — evidence that enters the hierarchy at this concept

Code
16 ranges343 lines · 2 files
Tests
0 tests

Contains — complete concept membership

All code (extent)
1525 ranges10317 lines · 55 files · Browse complete extent
All tests (intent)
4 testsBrowse complete intent

Neighbourhood graph

The orange circle is the focus. Violet and green circles are every ancestor and descendant, broader and narrower, at any distance; blue squares and pink diamonds are the introduced files and exact introduced tests of every visible concept, not only the focus's. Arrows point from broader to narrower concepts and bridge only concepts omitted from this view. Undirected links show source or test introduction. Concept and file size follows LOC; exact test nodes use test-count units.

Introduced files, introduced tests, and structurally relevant concept specialization

In the embedded map, ordinary wheel input scrolls the page; use the visible controls to zoom and drag to pan. Open the full-screen map for canvas navigation: wheel pans, Ctrl/Command plus wheel zooms, and arrow keys pan when this region is focused. On touch screens, open the full-screen map to pan or pinch. If JavaScript or WebGL is unavailable, use the native relationship evidence on this page.

Introduced files, introduced tests, and structurally relevant concept specializationtunnelAgentHostService.ts ×1 · 2 introduced LOCtunnelAgentHostService.t…tunnelAgentHostService.ts ×1 · 2 introduced LOCtunnelAgentHostService.t…tunnelAgentHostService.ts ×1 · 1 introduced LOCtunnelAgentHostService.t…tunnelAgentHostService.ts ×1 · 10 introduced LOCtunnelAgentHostService.t…tunnelAgentHostService.test|title=TunnelAgentHostService - withTimeout production constant is large enough to cover SDK keepalive windows|occurrence=1 · 0 introduced LOCtunnelAgentHostService.t…log.ts ×72 · 446 introduced LOClog.ts ×72buffer.test|title=Buffer Performance issue with VSBuffer#slice #76076|occurrence=1 · 0 introduced LOCbuffer.test|title=Buffer…contextkey.ts ×1 · 2 introduced LOCcontextkey.ts ×1contextkey.ts ×3 · 7 introduced LOCcontextkey.ts ×3async.ts ×202 · 1247 introduced LOCasync.ts ×202contextkey.ts ×1 · 3 introduced LOCcontextkey.ts ×1contextkey.ts ×1 · 2 introduced LOCcontextkey.ts ×1contextkey.ts ×1 · 3 introduced LOCcontextkey.ts ×1contextkey.ts ×1 · 2 introduced LOCcontextkey.ts ×1contextkey.ts ×2 · 3 introduced LOCcontextkey.ts ×2contextkey.ts ×1 · 2 introduced LOCcontextkey.ts ×1contextkey.ts ×2 · 3 introduced LOCcontextkey.ts ×2contextkey.ts ×2 · 3 introduced LOCcontextkey.ts ×2contextkey.ts ×1 · 2 introduced LOCcontextkey.ts ×1contextkey.ts ×1 · 4 introduced LOCcontextkey.ts ×1contextkey.ts ×201 · 796 introduced LOCcontextkey.ts ×201hash.ts ×17 · 74 introduced LOChash.ts ×17resources.ts ×23 · 253 introduced LOCresources.ts ×23network.ts ×20 · 292 introduced LOCnetwork.ts ×20strings.test|title=Strings trimWhitespace|occurrence=1 · 0 introduced LOCstrings.test|title=Strin…extpath.ts ×17 · 91 introduced LOCextpath.ts ×17strings.ts ×101 · 542 introduced LOCstrings.ts ×101timeTravelScheduler.ts ×1 · 35 introduced LOCtimeTravelScheduler.ts ×…traceLogger.ts ×3 · 98 introduced LOCtraceLogger.ts ×3processor.ts ×17 · 711 introduced LOCprocessor.ts ×17cancellation.test|title=CancellationToken None|occurrence=1 · 0 introduced LOCcancellation.test|title=…cancellation.ts ×18 · 90 introduced LOCcancellation.ts ×18event.ts ×1 · 1 introduced LOCevent.ts ×1event.ts ×4 · 9 introduced LOCevent.ts ×4event.ts ×2 · 6 introduced LOCevent.ts ×2event.ts ×93 · 864 introduced LOCevent.ts ×93buffer.ts ×42 · 483 introduced LOCbuffer.ts ×42scanner.ts ×13 · 13 introduced LOCscanner.ts ×13scanner.ts ×3 · 3 introduced LOCscanner.ts ×3scanner.ts ×1 · 1 introduced LOCscanner.ts ×1scanner.ts ×1 · 1 introduced LOCscanner.ts ×1scanner.ts ×1 · 1 introduced LOCscanner.ts ×1scanner.ts ×1 · 1 introduced LOCscanner.ts ×1scanner.ts ×1 · 1 introduced LOCscanner.ts ×1scanner.ts ×1 · 1 introduced LOCscanner.ts ×1scanner.ts ×36 · 181 introduced LOCscanner.ts ×36uuid.test|title=UUID generation|occurrence=1 · 0 introduced LOCuuid.test|title=UUID gen…uri.test|title=URI URI#file, win-speciale|occurrence=1, charCode.test|title=CharCode has good values|occurrence=1, +2 · 0 introduced LOCuri.test|title=URI URI#f…utils.ts ×3 · 9 introduced LOCutils.ts ×3instantiation.ts ×4 · 10 introduced LOCinstantiation.ts ×4nls.ts ×1 · 1 introduced LOCnls.ts ×1errorMessage.ts ×6 · 29 introduced LOCerrorMessage.ts ×6linkedList.ts ×13 · 44 introduced LOClinkedList.ts ×13nls.ts ×6 · 13 introduced LOCnls.ts ×6instantiation.ts ×5 · 111 introduced LOCinstantiation.ts ×5lifecycle.ts ×2 · 4 introduced LOClifecycle.ts ×2lifecycle.ts ×1 · 2 introduced LOClifecycle.ts ×1lifecycle.ts ×4 · 8 introduced LOClifecycle.ts ×4lifecycle.ts ×6 · 16 introduced LOClifecycle.ts ×6lazy.ts ×1 · 2 introduced LOClazy.ts ×1lazy.ts ×3 · 37 introduced LOClazy.ts ×3uuid.ts ×3 · 25 introduced LOCuuid.ts ×3lifecycle.ts ×1 · 2 introduced LOClifecycle.ts ×1lifecycle.ts ×1 · 2 introduced LOClifecycle.ts ×1uint.ts ×2 · 43 introduced LOCuint.ts ×2arrays.ts ×1 · 2 introduced LOCarrays.ts ×1lifecycle.ts ×1 · 3 introduced LOClifecycle.ts ×1map.ts ×97 · 3334 introduced LOCmap.ts ×97src/vs/base/common/arrays.ts · 949 LOCcommon/arrays.tssrc/vs/base/common/arraysFind.ts · 226 LOCcommon/arraysFind.tssrc/vs/base/common/assert.ts · 91 LOCcommon/assert.tssrc/vs/base/common/async.ts · 2749 LOCcommon/async.tssrc/vs/base/common/buffer.ts · 499 LOCcommon/buffer.tssrc/vs/base/common/cache.ts · 153 LOCcommon/cache.tssrc/vs/base/common/cancellation.ts · 206 LOCcommon/cancellation.tssrc/vs/base/common/charCode.ts · 450 LOCcommon/charCode.tssrc/vs/base/common/collections.ts · 176 LOCcommon/collections.tssrc/vs/base/common/errorMessage.ts · 113 LOCcommon/errorMessage.tssrc/vs/base/common/errors.ts · 357 LOCcommon/errors.tssrc/vs/base/common/event.ts · 1964 LOCcommon/event.tssrc/vs/base/common/extpath.ts · 433 LOCcommon/extpath.tssrc/vs/base/common/functional.ts · 32 LOCcommon/functional.tssrc/vs/base/common/hash.ts · 324 LOCcommon/hash.tssrc/vs/base/common/iterator.ts · 194 LOCcommon/iterator.tssrc/vs/base/common/lazy.ts · 57 LOCcommon/lazy.tssrc/vs/base/common/lifecycle.ts · 974 LOCcommon/lifecycle.tssrc/vs/base/common/linkedList.ts · 151 LOCcommon/linkedList.tssrc/vs/base/common/map.ts · 1016 LOCcommon/map.tssrc/vs/base/common/marshallingIds.ts · 33 LOCcommon/marshallingIds.tssrc/vs/base/common/network.ts · 440 LOCcommon/network.tssrc/vs/base/common/path.ts · 1589 LOCcommon/path.tssrc/vs/base/common/platform.ts · 281 LOCcommon/platform.tssrc/vs/base/common/process.ts · 76 LOCcommon/process.tssrc/vs/base/common/resources.ts · 444 LOCcommon/resources.tssrc/vs/base/common/stopwatch.ts · 41 LOCcommon/stopwatch.tssrc/vs/base/common/stream.ts · 790 LOCcommon/stream.tssrc/vs/base/common/strings.ts · 1413 LOCcommon/strings.tssrc/vs/base/common/symbols.ts · 9 LOCcommon/symbols.tssrc/vs/base/common/types.ts · 410 LOCcommon/types.tssrc/vs/base/common/uint.ts · 59 LOCcommon/uint.tssrc/vs/base/common/uri.ts · 754 LOCcommon/uri.tssrc/vs/base/common/uuid.ts · 70 LOCcommon/uuid.tssrc/vs/base/test/common/timeTravelScheduler.ts · 35 LOCcommon/timeTravelSchedul…src/vs/base/test/common/utils.ts · 107 LOCcommon/utils.tssrc/vs/base/test/common/virtualScheduling/embedding.ts · 89 LOCvirtualScheduling/embedd…src/vs/base/test/common/virtualScheduling/globalTimeApi.ts · 82 LOCvirtualScheduling/global…src/vs/base/test/common/virtualScheduling/index.ts · 36 LOCvirtualScheduling/index.…src/vs/base/test/common/virtualScheduling/loggingTimeApi.ts · 42 LOCvirtualScheduling/loggin…src/vs/base/test/common/virtualScheduling/processor.ts · 384 LOCvirtualScheduling/proces…src/vs/base/test/common/virtualScheduling/recordingTimeApi.ts · 98 LOCvirtualScheduling/record…src/vs/base/test/common/virtualScheduling/runWithFakedTimers.ts · 104 LOCvirtualScheduling/runWit…src/vs/base/test/common/virtualScheduling/timeApi.ts · 48 LOCvirtualScheduling/timeAp…src/vs/base/test/common/virtualScheduling/trace.ts · 172 LOCvirtualScheduling/trace.…src/vs/base/test/common/virtualScheduling/traceLogger.ts · 77 LOCvirtualScheduling/traceL…src/vs/base/test/common/virtualScheduling/virtualClock.ts · 121 LOCvirtualScheduling/virtua…src/vs/base/test/common/virtualScheduling/virtualTimeApi.ts · 194 LOCvirtualScheduling/virtua…src/vs/nls.ts · 244 LOCvs/nls.tssrc/vs/platform/agentHost/common/tunnelAgentHost.ts · 276 LOCcommon/tunnelAgentHost.t…src/vs/platform/agentHost/node/tunnelAgentHostService.ts · 390 LOCnode/tunnelAgentHostServ…src/vs/platform/contextkey/common/contextkey.ts · 2183 LOCcommon/contextkey.tssrc/vs/platform/contextkey/common/scanner.ts · 384 LOCcommon/scanner.tssrc/vs/platform/instantiation/common/instantiation.ts · 130 LOCcommon/instantiation.tssrc/vs/platform/log/common/log.ts · 926 LOCcommon/log.tsbuffer.test|title=Buffer Performance issue with VSBuffer#slice #76076|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/base/test/common/buffer.test|title=Buffer Performance issue with VSBuffer#slice #76076|occurrence=1buffer.test|title=Buffer…cancellation.test|title=CancellationToken None|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/base/test/common/cancellation.test|title=CancellationToken None|occurrence=1cancellation.test|title=…charCode.test|title=CharCode has good values|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/base/test/common/charCode.test|title=CharCode has good values|occurrence=1charCode.test|title=Char…path.test|title=Paths (Node Implementation) path|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/base/test/common/path.test|title=Paths (Node Implementation) path|occurrence=1path.test|title=Paths (N…strings.test|title=Strings trimWhitespace|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/base/test/common/strings.test|title=Strings trimWhitespace|occurrence=1strings.test|title=Strin…uri.test|title=URI File paths containing apostrophes break URI parsing and cannot be opened #276075|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/base/test/common/uri.test|title=URI File paths containing apostrophes break URI parsing and cannot be opened #276075|occurrence=1uri.test|title=URI File …uri.test|title=URI URI#file, win-speciale|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/base/test/common/uri.test|title=URI URI#file, win-speciale|occurrence=1uri.test|title=URI URI#f…uuid.test|title=UUID generation|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/base/test/common/uuid.test|title=UUID generation|occurrence=1uuid.test|title=UUID gen…tunnelAgentHostService.test|title=TunnelAgentHostService - withTimeout production constant is large enough to cover SDK keepalive windows|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/tunnelAgentHostService.test|title=TunnelAgentHostService - withTimeout production constant is large enough to cover SDK keepalive windows|occurrence=1tunnelAgentHostService.t…tunnelAgentHostService.test|title=TunnelAgentHostService - withTimeout rethrows the operation error verbatim when it rejects before the timeout|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/tunnelAgentHostService.test|title=TunnelAgentHostService - withTimeout rethrows the operation error verbatim when it rejects before the timeout|occurrence=1tunnelAgentHostService.t…tunnelAgentHostService.test|title=TunnelAgentHostService - withTimeout returns the operation result when it settles within the timeout|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/tunnelAgentHostService.test|title=TunnelAgentHostService - withTimeout returns the operation result when it settles within the timeout|occurrence=1tunnelAgentHostService.t…tunnelAgentHostService.test|title=TunnelAgentHostService - withTimeout throws a step-named timeout error when the operation hangs past the deadline|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/agentHost/test/node/tunnelAgentHostService.test|title=TunnelAgentHostService - withTimeout throws a step-named timeout error when the operation hangs past the deadline|occurrence=1tunnelAgentHostService.t…Focused concept · tunnelAgentHostService.ts ×14 · 343 introduced LOCtunnelAgentHostService.t…

Graph controls are ready.

Interactive rendering requires JavaScript and WebGL. Use the native relationship evidence on this page while the interactive map is unavailable.

Native relationship evidence

Every exact file and test below is linked only from the concept that introduces it.

Introduced tests

Every collected test enters the hierarchy at exactly one concept.

No tests are introduced at this concept. Its intent tests are introduced by other concepts.

Introduced code

Every collected source range enters the hierarchy at exactly one concept.

2 files ranked by introduced lines: 343 introduced LOC across 16 ranges. Expand a file to inspect source; the > gutter marks introduced lines.

src/vs/platform/agentHost/common/tunnelAgentHost.ts 255 introduced LOC · 2 ranges

Open complete file

1 > /*--------------------------------------------------------------------------------------------- tunnelAgentHost.ts
2 > * Copyright (c) Microsoft Corporation. All rights reserved.
3 > * Licensed under the MIT License. See License.txt in the project root for license information.
4 > *--------------------------------------------------------------------------------------------*/
5 >
6 > import { Event } from '../../../base/common/event.js';
7 > import { createDecorator } from '../../instantiation/common/instantiation.js';
8 > import type { IAgentHostSocketInfo } from './agentService.js';
9 >
10 > export const ITunnelAgentHostService = createDecorator<ITunnelAgentHostService>('tunnelAgentHostService');
11 >
12 > /**
13 > * IPC channel name for the shared-process tunnel service.
14 > */
15 > export const TUNNEL_AGENT_HOST_CHANNEL = 'tunnelAgentHost';
16 >
17 > /** Configuration key for the list of manually configured tunnel names. */
18 > export const TunnelAgentHostsSettingId = 'chat.remoteAgentTunnels';
19 >
20 > /** Minimum protocol version required for agent host connections. */
21 > export const TUNNEL_MIN_PROTOCOL_VERSION = 5;
22 >
23 > /** Well-known port for the agent host on tunnel machines. */
24 > export const TUNNEL_AGENT_HOST_PORT = 31546;
25 >
26 > /** Label used to identify VS Code server launcher tunnels. */
27 > export const TUNNEL_LAUNCHER_LABEL = 'vscode-server-launcher';
28 >
29 > /** Address prefix for tunnel-backed connections (e.g. `tunnel:myTunnelId`). */
30 > export const TUNNEL_ADDRESS_PREFIX = 'tunnel:';
31 >
32 > /** Prefix for protocol version tags. */
33 > export const PROTOCOL_VERSION_TAG_PREFIX = 'protocolv';
34 >
35 > /**
36 > * Parse tunnel tags to extract display name and protocol version.
37 > * Follows the convention from the vscode-remote-tunnels SDK: the
38 > * first label that is not `vscode-server-launcher`, does not start
39 > * with `_`, and is not a `protocolvN` tag is the display name.
40 > */
41 > export class TunnelTags {
42 > public readonly protocolVersion: number = 2;
43 > public readonly name: string | undefined;
44 >
45 > constructor(readonly value: readonly string[] | undefined) {
46 if (value) {
47 let protocolVersion: number | undefined;
65 }
66 }
68 >
69 > /** A recently used tunnel cached in storage. */
70 > export interface ICachedTunnel {
71 > readonly tunnelId: string;
72 > readonly clusterId: string;
73 > readonly name: string;
74 > readonly authProvider?: 'github' | 'microsoft';
75 > }
76 >
77 > /** Information about a discovered dev tunnel with an agent host. */
78 > export interface ITunnelInfo {
79 > /** The tunnel's unique identifier. */
80 > readonly tunnelId: string;
81 > /** The cluster region where the tunnel is hosted. */
82 > readonly clusterId: string;
83 > /** Display name derived from tunnel tags or tunnel name. */
84 > readonly name: string;
85 > /** All tags/labels on the tunnel. */
86 > readonly tags: readonly string[];
87 > /** Parsed protocol version from tags. */
88 > readonly protocolVersion: number;
89 > /** Number of hosts currently accepting connections (0 = offline). */
90 > readonly hostConnectionCount: number;
91 > }
92 >
93 > /**
94 > * Serializable result from a successful tunnel connect operation.
95 > * Returned over IPC from the shared process.
96 > */
97 > export interface ITunnelConnectResult {
98 > /** Unique identifier for this connection's relay channel. */
99 > readonly connectionId: string;
100 > /** Display-friendly address (e.g. "tunnel:myTunnel"). */
101 > readonly address: string;
102 > /** Display name for the tunnel. */
103 > readonly name: string;
104 > /** Connection token derived from the tunnel ID. */
105 > readonly connectionToken: string;
106 > }
107 >
108 > /**
109 > * A message relayed from a remote agent host through the tunnel.
110 > * The shared process acts as a WebSocket proxy, forwarding JSON
111 > * messages bidirectionally between the tunnel and the renderer via IPC.
112 > */
113 > export interface ITunnelRelayMessage {
114 > readonly connectionId: string;
115 > readonly data: string;
116 > }
117 >
118 > /**
119 > * Main-process (shared process) service that manages dev tunnel
120 > * connections. The renderer calls this over IPC and handles registration
121 > * with {@link IRemoteAgentHostService} locally.
122 > */
123 > export const ITunnelAgentHostMainService = createDecorator<ITunnelAgentHostMainService>('tunnelAgentHostMainService');
124 >
125 > export interface ITunnelAgentHostMainService {
126 > readonly _serviceBrand: undefined;
127 >
128 > /** Fires when a message is received from a remote agent host via the tunnel relay. */
129 > readonly onDidRelayMessage: Event<ITunnelRelayMessage>;
130 >
131 > /** Fires when a relay connection to a remote agent host closes. */
132 > readonly onDidRelayClose: Event<string /* connectionId */>;
133 >
134 > /**
135 > * List dev tunnels associated with the user's account that have
136 > * the `vscode-server-launcher` label and a protocol version tag
137 > * of at least {@link TUNNEL_MIN_PROTOCOL_VERSION}.
138 > *
139 > * @param token The user's access token (GitHub or Microsoft).
140 > * @param authProvider The auth provider that issued the token.
141 > * @param additionalTunnelNames Optional tunnel names to look up
142 > * in addition to the account-wide enumeration.
143 > */
144 > listTunnels(token: string, authProvider: 'github' | 'microsoft', additionalTunnelNames?: string[]): Promise<ITunnelInfo[]>;
145 >
146 > /**
147 > * Connect to a tunnel's agent host via the dev tunnels relay and
148 > * begin relaying WebSocket messages through IPC.
149 > *
150 > * @param token The user's access token (GitHub or Microsoft).
151 > * @param authProvider The auth provider that issued the token.
152 > * @param tunnelId The tunnel ID to connect to.
153 > * @param clusterId The cluster region of the tunnel.
154 > */
155 > connect(token: string, authProvider: 'github' | 'microsoft', tunnelId: string, clusterId: string): Promise<ITunnelConnectResult>;
156 >
157 > /**
158 > * Send a message to a remote agent host through the tunnel relay.
159 > */
160 > relaySend(connectionId: string, message: string): Promise<void>;
161 >
162 > /**
163 > * Disconnect a tunnel relay connection.
164 > */
165 > disconnect(connectionId: string): Promise<void>;
166 > }
167 >
168 > /**
169 > * Renderer-side service that manages dev tunnel agent host connections.
170 > * Uses the shared-process {@link ITunnelAgentHostMainService} for
171 > * actual tunnel SDK operations and registers connections with
172 > * {@link IRemoteAgentHostService}.
173 > */
174 > export interface ITunnelAgentHostService {
175 > readonly _serviceBrand: undefined;
176 >
177 > /** Fires when the set of available tunnels changes. */
178 > readonly onDidChangeTunnels: Event<void>;
179 >
180 > /**
181 > * Enumerate available dev tunnels with agent host support.
182 > * When {@link options.silent} is `true`, uses cached tokens without
183 > * prompting the user. Returns an empty array if no cached token.
184 > */
185 > listTunnels(options?: { silent?: boolean }): Promise<ITunnelInfo[]>;
186 >
187 > /**
188 > * Connect to a tunnel's agent host and register the connection
189 > * with {@link IRemoteAgentHostService}.
190 > *
191 > * @param tunnel The tunnel to connect to.
192 > * @param authProvider Optional auth provider to use. If omitted, uses cached/last known.
193 > */
194 > connect(tunnel: ITunnelInfo, authProvider?: 'github' | 'microsoft'): Promise<void>;
195 >
196 > /**
197 > * Disconnect from a tunnel agent host.
198 > */
199 > disconnect(address: string): Promise<void>;
200 >
201 > /** Get the list of recently used (cached) tunnels. */
202 > getCachedTunnels(): ICachedTunnel[];
203 >
204 > /** Cache a tunnel as recently used. */
205 > cacheTunnel(tunnel: ITunnelInfo, authProvider?: 'github' | 'microsoft'): void;
206 >
207 > /** Remove a tunnel from the cache. */
208 > removeCachedTunnel(tunnelId: string): void;
209 >
210 > /** Whether startup/background auto-connect should skip this tunnel because the user disconnected it. */
211 > isAutoConnectSuppressed(tunnelId: string): boolean;
212 >
213 > /** Remember that the user explicitly disconnected this tunnel, so startup/background auto-connect skips it. */
214 > suppressAutoConnect(tunnelId: string): void;
215 >
216 > /** Clear a previous user-disconnect marker after the user explicitly reconnects this tunnel. */
217 > clearAutoConnectSuppression(tunnelId: string): void;
218 >
219 > /**
220 > * Determine which auth provider has an existing cached session.
221 > * When {@link silent} is true, does not prompt the user.
222 > * Returns `undefined` if no cached session is available.
223 > */
224 > getAuthProvider(options?: { silent?: boolean }): Promise<'github' | 'microsoft' | undefined>;
225 > }
226 >
227 > // ---- Tunnel hosting (exposing the local agent host to remote clients) --------
228 >
229 > /** IPC channel name for the tunnel host service. */
230 > export const TUNNEL_HOST_CHANNEL = 'tunnelHost';
231 >
232 > /** Output channel ID for the tunnel host logs. */
233 > export const TUNNEL_HOST_LOG_ID = 'tunnelHostService';
234 >
235 > /** Information about an actively hosted tunnel. */
236 > export interface ITunnelHostInfo {
237 > readonly tunnelName: string;
238 > readonly tunnelId: string;
239 > readonly clusterId: string;
240 > readonly domain: string;
241 > }
242 >
243 > /** Status of the tunnel host. */
244 > export type TunnelHostStatus =
245 > | { readonly active: false }
246 > | { readonly active: true; readonly info: ITunnelHostInfo };
247 >
248 > /**
249 > * Shared-process service that hosts a dev tunnel using `TunnelRelayTunnelHost`
250 > * and pipes incoming connections to the local agent host.
251 > */
252 > export const ITunnelAgentHostHostingService = createDecorator<ITunnelAgentHostHostingService>('tunnelAgentHostHostingService');
253 >
254 > export interface ITunnelAgentHostHostingService {
255 > readonly _serviceBrand: undefined;
256 >
257 > /** Fires when the hosting status changes. */
258 > readonly onDidChangeStatus: Event<TunnelHostStatus>;
259 >
260 > /**
261 > * Start hosting a dev tunnel that forwards connections to the local
262 > * agent host. Creates a tunnel with the appropriate labels and port
263 > * configuration, then connects a `TunnelRelayTunnelHost`.
264 > *
265 > * @param token The user's access token.
266 > * @param authProvider The auth provider that issued the token.
267 > * @param socketInfo Socket path for the local agent host.
268 > */
269 > startHosting(token: string, authProvider: 'github' | 'microsoft', socketInfo: IAgentHostSocketInfo): Promise<ITunnelHostInfo>;
270 >
271 > /** Stop hosting and clean up the tunnel. */
272 > stopHosting(): Promise<void>;
273 >
274 > /** Get the current hosting status. */
275 > getStatus(): Promise<TunnelHostStatus>;
276 > }
src/vs/platform/agentHost/node/tunnelAgentHostService.ts 88 introduced LOC · 14 ranges

Open complete file

1 > /*--------------------------------------------------------------------------------------------- tunnelAgentHostService.ts
2 > * Copyright (c) Microsoft Corporation. All rights reserved.
3 > * Licensed under the MIT License. See License.txt in the project root for license information.
4 > *--------------------------------------------------------------------------------------------*/
5 >
6 > import type { Tunnel } from '@microsoft/dev-tunnels-contracts';
7 > import type { TunnelManagementHttpClient } from '@microsoft/dev-tunnels-management';
8 > import { createHash } from 'crypto';
9 > import type WebSocket from 'ws';
10 > import { Emitter, Event } from '../../../base/common/event.js';
11 > import { Disposable } from '../../../base/common/lifecycle.js';
12 > import { raceTimeout } from '../../../base/common/async.js';
13 > import { generateUuid } from '../../../base/common/uuid.js';
14 > import { ILogService } from '../../log/common/log.js';
15 > import {
16 > ITunnelAgentHostMainService,
17 > TUNNEL_ADDRESS_PREFIX,
18 > TUNNEL_AGENT_HOST_PORT,
19 > TUNNEL_LAUNCHER_LABEL,
20 > TUNNEL_MIN_PROTOCOL_VERSION,
21 > TunnelTags,
22 > type ITunnelConnectResult,
23 > type ITunnelInfo,
24 > type ITunnelRelayMessage,
25 > } from '../common/tunnelAgentHost.js';
26 >
27 > const LOG_PREFIX = '[TunnelAgentHost]';
28 >
29 > /**
30 > * Per-step timeout for the dev-tunnels SDK calls inside {@link TunnelAgentHostMainService.connect}.
31 > *
32 > * Without this, a silently dropped network (TCP half-open, host gone but relay still
33 > * accepting our messages) can leave `relayClient.connect()`,
34 > * `waitForForwardedPort()`, `connectToForwardedPort()`, or the WebSocket `'open'`
35 > * event pending forever — which in turn hangs the renderer's
36 > * `_tunnelService.connect(...)` await, leaving the per-host `_pendingConnects`
37 > * flag set and effectively disabling auto-reconnect for the lifetime of the
38 > * shared process.
39 > */
40 > export const TUNNEL_STEP_TIMEOUT_MS = 30_000;
41 >
42 export async function withTimeout<T>(
43 op: () => Promise<T>,
55 return result as T;
56 }
58 > /**
59 > * Derive a connection token from a tunnel ID using the same convention
60 > * as the VS Code CLI (see `get_connection_token` in cli/src/commands/tunnels.rs).
61 > */
62 function deriveConnectionToken(tunnelId: string): string {
63 const hash = createHash('sha256');
69 return result;
70 }
72 > /** State for a single active tunnel relay connection. */
73 > class TunnelConnection extends Disposable {
74 > private readonly _onDidClose = this._register(new Emitter<void>());
75 > readonly onDidClose = this._onDidClose.event;
76 >
77 > private _closed = false;
78 >
79 > constructor(
80 readonly connectionId: string,
81 readonly address: string,
87 super();
88 }
90 > override dispose(): void {
91 if (!this._closed) {
92 this._closed = true;
97 super.dispose();
98 }
100 > relaySend(data: string): void {
101 this._relay.send(data);
102 }
104 >
105 > export class TunnelAgentHostMainService extends Disposable implements ITunnelAgentHostMainService {
106 > declare readonly _serviceBrand: undefined;
107 >
108 > private readonly _onDidRelayMessage = this._register(new Emitter<ITunnelRelayMessage>());
109 > readonly onDidRelayMessage: Event<ITunnelRelayMessage> = this._onDidRelayMessage.event;
110 >
111 > private readonly _onDidRelayClose = this._register(new Emitter<string>());
112 > readonly onDidRelayClose: Event<string> = this._onDidRelayClose.event;
113 >
114 > private readonly _connections = new Map<string, TunnelConnection>();
115 >
116 > constructor(
117 @ILogService private readonly _logService: ILogService,
118 ) {
119 super();
120 }
122 > async listTunnels(token: string, authProvider: 'github' | 'microsoft', additionalTunnelNames?: string[]): Promise<ITunnelInfo[]> {
123 const client = await this._createManagementClient(token, authProvider);
124 const results: ITunnelInfo[] = [];
172 return results;
173 }
175 > async connect(token: string, authProvider: 'github' | 'microsoft', tunnelId: string, clusterId: string): Promise<ITunnelConnectResult> {
176 // Tear down any existing connection to this tunnel first.
177 // Each connect() call creates a fresh relay with its own protocol
278 return { connectionId, address, name, connectionToken };
279 }
281 > async relaySend(connectionId: string, message: string): Promise<void> {
282 const conn = this._connections.get(connectionId);
283 if (conn) {
285 }
286 }
288 > async disconnect(connectionId: string): Promise<void> {
289 const conn = this._connections.get(connectionId);
290 if (conn) {
292 }
293 }
295 > private async _createManagementClient(token: string, authProvider: 'github' | 'microsoft'): Promise<TunnelManagementHttpClient> {
296 const mgmt = await import('@microsoft/dev-tunnels-management');
297 const authHeader = authProvider === 'github' ? `github ${token}` : `Bearer ${token}`;
303 );
304 }
306 > private _parseTunnelInfo(tunnel: Tunnel): ITunnelInfo | undefined {
307 const labels = tunnel.labels ?? [];
308 const tags = new TunnelTags(labels);
330 };
331 }
333 > private async _createWebSocketRelay(
334 portStream: NodeJS.ReadWriteStream,
335 connectionToken: string,