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 <path-to-file`

It should open in your existing code-server instance.

When the extension host is terminated, the socket is unregistered.

Index: code-server/lib/vscode/src/vs/workbench/api/node/extHostExtensionService.ts
===================================================================
--- code-server.orig/lib/vscode/src/vs/workbench/api/node/extHostExtensionService.ts
+++ code-server/lib/vscode/src/vs/workbench/api/node/extHostExtensionService.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 * as performance from '../../../base/common/performance.js';
 import type * as vscode from 'vscode';
 import { createApiFactoryAndRegisterActors } from '../common/extHost.api.impl.js';
@@ -18,6 +19,7 @@ import { ExtensionRuntime } from '../com
 import { CLIServer } from './extHostCLIServer.js';
 import { realpathSync } from '../../../base/node/pfs.js';
 import { ExtHostConsoleForwarder } from './extHostConsoleForwarder.js';
+import { IExtHostWorkspace } from '../common/extHostWorkspace.js';
 import { ExtHostDiskFileSystemProvider } from './extHostDiskFileSystemProvider.js';
 import nodeModule from 'node:module';
 import { assertType } from '../../../base/common/types.js';
@@ -226,6 +228,52 @@ export class ExtHostExtensionService ext
 
 		performance.mark('code/extHost/didInitAPI');
 
+		(async () => {
+			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<void>((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';
@@ -449,7 +450,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));
