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
5 changes: 4 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -109,5 +109,8 @@ jobs:
- name: Install dependencies
run: npm ci

- name: Run tests
run: npm test

- name: Package check (dry run)
run: npx @vscode/vsce package --out tmp.vsix && rm -f tmp.vsix
run: npm run package:check
11 changes: 11 additions & 0 deletions iii-lsp-vscode/AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# iii-lsp-vscode Agent Notes

Use containers for Node commands. Do not install host-global Node packages.

```bash
cd iii-lsp-vscode
docker build -t iii-lsp-vscode-dev .
docker run --rm -u "$(id -u):$(id -g)" -v "$PWD:/workspace" -w /workspace iii-lsp-vscode-dev npm ci
docker run --rm -u "$(id -u):$(id -g)" -v "$PWD:/workspace" -w /workspace iii-lsp-vscode-dev npm test
docker run --rm -u "$(id -u):$(id -g)" -v "$PWD:/workspace" -w /workspace iii-lsp-vscode-dev npm run package:check
```
3 changes: 3 additions & 0 deletions iii-lsp-vscode/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
FROM node:20-bookworm

WORKDIR /workspace
Comment on lines +1 to +3
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail
# Verify whether a non-root USER is set in the Dockerfile.
rg -n '^\s*USER\s+' iii-lsp-vscode/Dockerfile || true

Repository: iii-hq/workers

Length of output: 40


Add a non-root default user.

The Dockerfile currently defaults to the root user. Add a USER directive to run containers as a non-root user by default.

Proposed fix
 FROM node:20-bookworm
 
 WORKDIR /workspace
+USER node
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
FROM node:20-bookworm
WORKDIR /workspace
FROM node:20-bookworm
WORKDIR /workspace
USER node
🧰 Tools
🪛 Trivy (0.69.3)

[error] 1-1: Image user should not be 'root'

Specify at least 1 USER command in Dockerfile with non-root user as argument

Rule: DS-0002

Learn more

(IaC/Dockerfile)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@iii-lsp-vscode/Dockerfile` around lines 1 - 3, The image currently runs as
root; update the Dockerfile to create or use a non-root user and switch to it
with a USER directive: add steps after WORKDIR to create a dedicated user/group
(or use the existing node user), ensure /workspace is owned by that user (chown)
and any required file permissions are set, and then add USER <username> so the
container runs non-root by default; reference the existing WORKDIR /workspace
and the Dockerfile's USER directive when making the change.

29 changes: 29 additions & 0 deletions iii-lsp-vscode/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
.PHONY: image install test package-check build install-cursor clean

IMAGE ?= iii-lsp-vscode-dev
VSIX ?= iii-lsp.vsix
NPM_CACHE ?= /tmp/npm-cache

DOCKER_RUN = docker run --rm -u "$$(id -u):$$(id -g)" -e npm_config_cache=$(NPM_CACHE) -v "$(CURDIR):/workspace" -w /workspace $(IMAGE)

image:
docker build -t $(IMAGE) .

install: image
$(DOCKER_RUN) npm ci

test: image
$(DOCKER_RUN) npm test

package-check: image
$(DOCKER_RUN) npm run package:check
Comment on lines +15 to +19
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

test and package-check can fail on a clean checkout.

Line 15-Line 19 don’t ensure dependencies are installed before running npm commands.

🔧 Proposed fix
-test: image
+test: install
 	$(DOCKER_RUN) npm test
 
-package-check: image
+package-check: install
 	$(DOCKER_RUN) npm run package:check
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@iii-lsp-vscode/Makefile` around lines 15 - 19, The Makefile targets test and
package-check can run on a clean checkout without installing dependencies;
update the test and package-check targets (and/or add a deps target) so they
ensure npm dependencies are installed before running commands—for example, run
$(DOCKER_RUN) npm ci (or add a deps target that runs $(DOCKER_RUN) npm ci and
make test and package-check depend on deps) prior to invoking $(DOCKER_RUN) npm
test and $(DOCKER_RUN) npm run package:check respectively.


build: image
$(DOCKER_RUN) npm ci
$(DOCKER_RUN) npx vsce package --out $(VSIX)

install-cursor: build
cursor --install-extension $(VSIX) --force

clean:
rm -f $(VSIX) iii-lsp-cursor.vsix iii-lsp-smoke.vsix tmp.vsix
39 changes: 29 additions & 10 deletions iii-lsp-vscode/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# III Language Server - VS Code Extension

Autocompletion, hover documentation, and diagnostics for [III engine](https://github.com/iii-org) functions and triggers.
Autocompletion, hover documentation, and diagnostics for [III engine](https://github.com/iii-hq/iii) functions and triggers.

![III LSP demo](./lsp.gif)

## Supported Languages

Expand All @@ -10,21 +12,20 @@ Autocompletion, hover documentation, and diagnostics for [III engine](https://gi

## Prerequisites

1. **iii-lsp binary** - Build it from the `iii-lsp/` crate:
1. **iii-lsp binary** - The extension downloads and installs the pinned `iii-lsp/v0.1.0` binary on first activation.

```bash
cd iii-lsp
cargo build --release
```
The binary is stored under VS Code's extension global storage directory and the absolute path is saved to `iii-lsp.serverPath` in global settings.

Then either:
- Add `iii-lsp/target/release` to your `PATH`, or
- Set the binary path in the extension settings (see below)
To use a custom binary instead, set `iii-lsp.serverPath` to an existing executable path before activation.

2. **III engine** running locally (default: `ws://127.0.0.1:49134`)

## Installation

After the extension is installed, open a supported TypeScript, TSX, Python, or Rust file to activate it. On first activation, the extension downloads the matching `iii-lsp/v0.1.0` binary, verifies its SHA-256 checksum, installs it under extension global storage, and saves the installed path to `iii-lsp.serverPath`.

If automatic install fails, the extension warns and falls back to the configured `iii-lsp.serverPath` or `iii-lsp` on `PATH`.

### From source (development)

1. Install dependencies:
Expand Down Expand Up @@ -62,11 +63,29 @@ Autocompletion, hover documentation, and diagnostics for [III engine](https://gi
code --install-extension iii-lsp-*.vsix
```

### Local smoke test with Cursor

Build a local VSIX and install it in Cursor:

```bash
cd iii-lsp-vscode
make build
cursor --install-extension iii-lsp.vsix --force
```

Open a supported file to activate the extension:

```bash
cursor ../iii-lsp/src/main.rs
```

After activation, `iii-lsp.serverPath` should point to the downloaded binary in Cursor settings. To install the same VSIX in VS Code instead, replace `cursor` with `code`.

## Settings

| Setting | Default | Description |
|---------|---------|-------------|
| `iii-lsp.serverPath` | `""` (uses `iii-lsp` from PATH) | Path to the `iii-lsp` binary |
| `iii-lsp.serverPath` | `""` (auto-filled after first activation) | Path to the installed or custom `iii-lsp` binary |
| `iii-lsp.engineUrl` | `ws://127.0.0.1:49134` | WebSocket URL of the III engine |

Configure via **Settings** > search "III LSP", or in `settings.json`:
Expand Down
20 changes: 16 additions & 4 deletions iii-lsp-vscode/extension.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,24 @@
const { workspace } = require("vscode");
const vscode = require("vscode");
const { LanguageClient, TransportKind } = require("vscode-languageclient/node");

const { ensureServerBinary } = require("./installer");

let client;

function activate(context) {
const config = workspace.getConfiguration("iii-lsp");
const serverPath = config.get("serverPath") || "iii-lsp";
async function activate(context) {
const config = vscode.workspace.getConfiguration("iii-lsp");
const engineUrl = config.get("engineUrl") || "ws://127.0.0.1:49134";
let serverPath;

try {
serverPath = await ensureServerBinary(context, vscode);
} catch (error) {
const message = error instanceof Error ? error.message : String(error);
vscode.window.showWarningMessage(
`Failed to install iii-lsp binary. Falling back to configured path or PATH lookup. ${message}`
);
serverPath = config.get("serverPath") || "iii-lsp";
}

const serverOptions = {
run: {
Expand Down
Loading
Loading