Store the IPC socket with workspace metadata. This lets us use it to open files inside code-server from outside of code-server. To test this: 1. run code-server 2. open file outside of code-server i.e. `code-server { + const socketPath = process.env['VSCODE_IPC_HOOK_CLI']; + const codeServerSocketPath = process.env['CODE_SERVER_SESSION_SOCKET'] + if (!socketPath || !codeServerSocketPath) { + return; + } + const workspace = this._instaService.invokeFunction((accessor) => { + const workspaceService = accessor.get(IExtHostWorkspace); + return workspaceService.workspace; + }); + const entry = { + workspace, + socketPath + }; + const message = JSON.stringify({entry}); + await new Promise((resolve, reject) => { + const opts: _http.RequestOptions = { + path: '/add-session', + socketPath: codeServerSocketPath, + method: 'POST', + headers: { + 'content-type': 'application/json', + } + }; + const req = _http.request(opts, (res) => { + res.on('error', reject); + res.on('end', () => { + try { + if (res.statusCode === 200) { + resolve(); + } else { + reject(new Error('Unexpected status code: ' + res.statusCode)); + } + } catch (e: unknown) { + reject(e); + } + }); + }); + req.on('error', reject); + req.write(message); + req.end(); + }); + })().catch(error => { + this._logService.error(error); + }); + // Do this when extension service exists, but extensions are not being activated yet. const configProvider = await this._extHostConfiguration.getConfigProvider(); await connectProxyResolver(this._extHostWorkspace, configProvider, this, this._logService, this._mainThreadTelemetryProxy, this._initData, this._store); Index: code-server/lib/vscode/src/vs/workbench/api/node/extensionHostProcess.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/workbench/api/node/extensionHostProcess.ts +++ code-server/lib/vscode/src/vs/workbench/api/node/extensionHostProcess.ts @@ -3,6 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import * as _http from 'http'; import minimist from 'minimist'; import * as nativeWatchdog from 'native-watchdog'; import * as net from 'net'; @@ -422,7 +423,28 @@ async function startExtensionHostProcess ); // rewrite onTerminate-function to be a proper shutdown - onTerminate = (reason: string) => extensionHostMain.terminate(reason); + onTerminate = (reason: string) => { + extensionHostMain.terminate(reason); + + const socketPath = process.env['VSCODE_IPC_HOOK_CLI']; + const codeServerSocketPath = process.env['CODE_SERVER_SESSION_SOCKET'] + if (!socketPath || !codeServerSocketPath) { + return; + } + const message = JSON.stringify({socketPath}); + const opts: _http.RequestOptions = { + path: '/delete-session', + socketPath: codeServerSocketPath, + method: 'POST', + headers: { + 'content-type': 'application/json', + 'accept': 'application/json' + } + }; + const req = _http.request(opts); + req.write(message); + req.end(); + }; } startExtensionHostProcess().catch((err) => console.log(err));