From 78f262854c7bab681b087c74cceda2ee81b31c35 Mon Sep 17 00:00:00 2001 From: Hendrik van Antwerpen Date: Thu, 29 Jan 2026 12:10:54 +0100 Subject: [PATCH] Support environment variables in server command --- clients/typescript/CHANGELOG.md | 8 ++++++- clients/typescript/README.md | 10 +++++++-- clients/typescript/package.json | 2 +- clients/typescript/src/__generated/version.ts | 2 +- clients/typescript/src/cli.ts | 22 +++++++++++++------ clients/typescript/src/server.ts | 19 +++++++++++----- 6 files changed, 46 insertions(+), 17 deletions(-) diff --git a/clients/typescript/CHANGELOG.md b/clients/typescript/CHANGELOG.md index 512df47b..ed383f50 100644 --- a/clients/typescript/CHANGELOG.md +++ b/clients/typescript/CHANGELOG.md @@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.5.3] - 2025-01-29 + +### Fixed + +- The `server` command now also respects the `NUANCED_LSP_CONTAINER_NAME` + and `NUANCED_LSP_PORT` environment variables. + ## [0.5.2] - 2025-01-21 ### Fixed @@ -12,7 +19,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Check that the workspace is not specified if `server` is given a container name. - ## [0.5.1] - 2025-01-21 ### Changed diff --git a/clients/typescript/README.md b/clients/typescript/README.md index 150c7180..738756d7 100644 --- a/clients/typescript/README.md +++ b/clients/typescript/README.md @@ -176,9 +176,15 @@ nuanced-lsp up /path/to/workspace \ --language-image-version 1.0.0 ``` -**Environment variables** (when used via Nuanced MCP): +**Environment variables**: -When Nuanced LSP is run through the Nuanced MCP server, you can override images using environment variables: +It is also possible to override some aspects of the containers with the following environment variables: + +- `NUANCED_LSP_CONTAINER_NAME` - Set the name of the container to start or use +- `NUANCED_LSP_PORT` - Set the port at which the Nuanced LSP API is exposed +- `NUANCED_LSP_TIMEOUT` - Set the timeout for API requests + +The following variables can be used to override the service and language images that are used: - `CONTAINER_REGISTRY` - Override the container registry - `LANGUAGE_IMAGE_VERSION` - Override the language image version diff --git a/clients/typescript/package.json b/clients/typescript/package.json index fa6a6b9b..6d097da9 100644 --- a/clients/typescript/package.json +++ b/clients/typescript/package.json @@ -1,6 +1,6 @@ { "name": "@nuanced-dev/lsp", - "version": "0.5.2", + "version": "0.5.3", "description": "TypeScript library and CLI for Nuanced LSP", "license": "MIT", "author": "Nuanced", diff --git a/clients/typescript/src/__generated/version.ts b/clients/typescript/src/__generated/version.ts index cb73720f..93400415 100644 --- a/clients/typescript/src/__generated/version.ts +++ b/clients/typescript/src/__generated/version.ts @@ -1,3 +1,3 @@ // AUTO-GENERATED FILE. Do not edit. // Generated by scripts/generate-version.mjs -export const VERSION = "0.5.2"; +export const VERSION = "0.5.3"; diff --git a/clients/typescript/src/cli.ts b/clients/typescript/src/cli.ts index 396cb186..e7e9246d 100644 --- a/clients/typescript/src/cli.ts +++ b/clients/typescript/src/cli.ts @@ -262,27 +262,35 @@ async function serverCommand( workspace: string | undefined, opts: ServerCommandOptions, ): Promise { + let containerName = + opts.containerName ?? process.env.NUANCED_LSP_CONTAINER_NAME; + let lspPort = + opts.hostPort ?? + (process.env.NUANCED_LSP_PORT + ? parseInt(process.env.NUANCED_LSP_PORT) + : undefined); + // Validate that exactly one of workspace or containerName is provided - if ( - (opts.containerName && workspace) || - (!opts.containerName && !workspace) - ) { + if ((containerName && workspace) || (!containerName && !workspace)) { log.err( "Must specify either workspace or --container-name. Provide a workspace to start a new container, or --container-name to use an existing one.", ); process.exit(1); } + containerName ??= await generateRandomContainerName(); + lspPort ??= 0; + const client = await lspClient({ ...opts, - containerName: opts.containerName ?? (await generateRandomContainerName()), - lspPort: opts.hostPort ?? 0, + containerName, + lspPort, }); try { // Run the LSP server stdio loop const { runLspServer } = await import("./server.js"); - await runLspServer(client, workspace!, opts, process.stdin, process.stdout); + await runLspServer(client, workspace, opts, process.stdin, process.stdout); } catch { // Fatal errors are already logged via window/logMessage process.exitCode = 1; diff --git a/clients/typescript/src/server.ts b/clients/typescript/src/server.ts index 19bf5b87..91573626 100644 --- a/clients/typescript/src/server.ts +++ b/clients/typescript/src/server.ts @@ -26,6 +26,7 @@ class LspServer { private readonly input: Readable; private readonly output: Writable; private readonly logLevel: MessageType; + private wasStarted = false; private shutdownReceived = false; private isShuttingDown = false; private ws: WebSocket | null = null; @@ -65,14 +66,20 @@ class LspServer { } private async startServer(): Promise { - if (!this.opts.containerName) { + // start container if it isn't running yet + if (isErr(await this.client.status())) { if (!this.workspace) { throw new Error( "Workspace is required when not using an existing container", ); } - const res = await this.client.up(this.workspace, { + await this.sendLogMessage( + MessageType.Info, + "Starting LSP server container", + ); + + const upRes = await this.client.up(this.workspace, { containerRegistry: this.opts.containerRegistry, languageImageVersion: this.opts.languageImageVersion, serviceImageVersion: this.opts.serviceImageVersion, @@ -84,13 +91,15 @@ class LspServer { envFile: this.opts.envFile, }); - if (isErr(res)) { + if (isErr(upRes)) { await this.sendLogMessage( MessageType.Error, - `Failed to start LSP server container: ${JSON.stringify(res.data)}`, + `Failed to start LSP server container: ${JSON.stringify(upRes.data)}`, ); throw new Error("Failed to start container"); } + + this.wasStarted = true; } await this.waitUntilServerIsHealthy(); @@ -188,7 +197,7 @@ class LspServer { this.ws = null; } - if (!this.opts.containerName) { + if (this.wasStarted) { await this.client.down(); } }