Skip to content
Merged
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
8 changes: 7 additions & 1 deletion clients/typescript/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,20 @@ 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

- Check that the workspace is not specified if `server` is given a
container name.


## [0.5.1] - 2025-01-21

### Changed
Expand Down
10 changes: 8 additions & 2 deletions clients/typescript/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion clients/typescript/package.json
Original file line number Diff line number Diff line change
@@ -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",
Expand Down
2 changes: 1 addition & 1 deletion clients/typescript/src/__generated/version.ts
Original file line number Diff line number Diff line change
@@ -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";
22 changes: 15 additions & 7 deletions clients/typescript/src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -262,27 +262,35 @@ async function serverCommand(
workspace: string | undefined,
opts: ServerCommandOptions,
): Promise<void> {
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;
Expand Down
19 changes: 14 additions & 5 deletions clients/typescript/src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -65,14 +66,20 @@ class LspServer {
}

private async startServer(): Promise<void> {
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,
Expand All @@ -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();
Expand Down Expand Up @@ -188,7 +197,7 @@ class LspServer {
this.ws = null;
}

if (!this.opts.containerName) {
if (this.wasStarted) {
await this.client.down();
}
}
Expand Down
Loading