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
1 change: 1 addition & 0 deletions docs/dependency_maintenance.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ These are the dependencies we will keep relatively current. We'd like to upgrade
- **npm dependencies**
- pinned in: the `package.json` files under [`tooling/lsp-clients`](../tooling/lsp-clients) and [`tooling/language-server-protocol`](../tooling/language-server-protocol)
- check with: `pnpm outdated -r` from each workspace root
- after editing any of them: run `./gradlew tooling:lsp-clients:check` to regenerate all `pnpm-lock.yaml` files. Commit the pnpm-lock.yaml files.
- **Cargo dependencies**
- pinned in: [`lib-rust/kson/Cargo.toml`](../lib-rust/kson/Cargo.toml) and [`lib-rust/kson-sys/Cargo.toml`](../lib-rust/kson-sys/Cargo.toml)
- check with: `cargo update --dry-run` in each
Expand Down
8 changes: 3 additions & 5 deletions docs/release_process.md
Original file line number Diff line number Diff line change
Expand Up @@ -369,13 +369,11 @@ The Monaco editor integration is published to npm as `@kson_org/monaco-editor`.
3. Check what would be published:
```bash
cd tooling/lsp-clients/monaco
npm pack --dry-run
npm pack --dry-run # should show the dist/ directory
npm pkg get dependencies # should show no dependencies ("{}")
npm pkg get devDependencies # should show links to two other kson projects (among other dev dependencies)
```

`dist/` must be present, and the manifest must declare no `dependencies`. A `file:` dependency
here is a path that exists only on the machine that published it, so it installs as a dangling
link and breaks `npm ls` for everyone downstream.

4. Publish to npm:
```bash
npm login
Expand Down
19 changes: 9 additions & 10 deletions tooling/language-server-protocol/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,33 +14,32 @@ each editor and ensures that features are implemented in one place, improving pe
* **Document Formatting:** Automatically formats Kson files.
* **Semantic Highlighting:** Provides rich, context-aware syntax highlighting.

## Getting Started
## Local development

### Prerequisites
Use gradlew (from the repository root) to build and test this LSP implementation. Gradle uses pixi-managed Node.js 24
and pnpm. To run pnpm directly, use `./pixiw run pnpm` in this directory.

* Node.js (v20.0.0 or higher)
* pnpm (provided by the project's pixi environment)
### Build

### Installation
Run `npm_install` any time package.json is updated to regenerate the lock files.

```bash
pnpm install
./gradlew tooling:language-server-protocol:npm_install
```

### Build
Note: this also builds the `kson` and `kson-tooling` Kotlin/JS libraries that the project depends on.

To compile the TypeScript source code, run:

```bash
pnpm run compile
./gradlew tooling:language-server-protocol:npm_run_compile
```

### Testing

To run the test suite:

```bash
pnpm test
./gradlew tooling:language-server-protocol:npm_run_test
```

[1] Visual Studio Code. (2025). *Language Server Extension Guide*. Retrieved
Expand Down
12 changes: 7 additions & 5 deletions tooling/language-server-protocol/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,18 @@ plugins {
}

tasks {
val npmInstall = register<PixiExecTask>("npmInstall") {
// `--frozen-lockfile` gives reproducible installs from pnpm-lock.yaml;
// hoisted keeps a flat node_modules (npm-identical layout) while still
// hardlinking from pnpm's shared global store.
command=listOf("pnpm", "install", "--frozen-lockfile", "--config.node-linker=hoisted")
val npmInstall = register<PixiExecTask>("npm_install") {
// updates pnpm-lock.yaml files whenever package.json changes
command=listOf("pnpm", "install", "--no-frozen-lockfile")
dependsOn(":kson-lib:jsNodeProductionLibraryDistribution")
dependsOn(":kson-tooling-lib:jsNodeProductionLibraryDistribution")
doNotTrackState("pnpm already tracks its own state")
}

register("npmInstall") { // deprecated alias to npm_install
dependsOn(npmInstall)
}

register<PixiExecTask>("npm_run_compile") {
command=listOf("pnpm", "run", "compile")
dependsOn(npmInstall)
Expand Down
6 changes: 3 additions & 3 deletions tooling/language-server-protocol/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
},
"scripts": {
"compile": "tsc",
"test": "mocha 'out/test/**/*.test.js'"
"test": "mocha"
},
"keywords": [
"kson",
Expand All @@ -42,8 +42,8 @@
"node": "24.x"
},
"dependencies": {
"kson": "file:../../kson-lib/build/dist/js/productionLibrary",
"kson-tooling": "file:../../kson-tooling-lib/build/dist/js/productionLibrary",
"kson": "link:../../kson-lib/build/dist/js/productionLibrary",
"kson-tooling": "link:../../kson-tooling-lib/build/dist/js/productionLibrary",
"vscode-languageserver": "^9.0.1",
"vscode-languageserver-textdocument": "^1.0.12",
"vscode-uri": "^3.0.8"
Expand Down
20 changes: 4 additions & 16 deletions tooling/language-server-protocol/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions tooling/language-server-protocol/pnpm-workspace.yaml
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
allowBuilds:
esbuild: true

# Flat node_modules (npm's layout), while still hardlinking from pnpm's shared global store.
nodeLinker: hoisted
21 changes: 12 additions & 9 deletions tooling/lsp-clients/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,17 @@ plugins {
}

tasks {
val npmInstall = register<PixiExecTask>("npmInstall") {
// `--frozen-lockfile` gives reproducible installs from pnpm-lock.yaml;
// hoisted keeps a flat node_modules (npm-identical layout) while still
// hardlinking from pnpm's shared global store.
command=listOf("pnpm", "install", "--frozen-lockfile", "--config.node-linker=hoisted")
val npmInstall = register<PixiExecTask>("npm_install") {
// updates pnpm-lock.yaml files whenever package.json changes
command=listOf("pnpm", "install", "--no-frozen-lockfile")
doNotTrackState("pnpm already tracks its own state")
dependsOn(":tooling:language-server-protocol:npm_run_test")
}

register("npmInstall") { // deprecated alias to npm_install
dependsOn(npmInstall)
}

val playwrightInstall = register<PixiExecTask>("playwrightInstall") {
command=listOf("pnpm", "exec", "playwright", "install", "chromium")
doNotTrackState("playwright already tracks its own state")
Expand Down Expand Up @@ -80,8 +82,9 @@ tasks {

// `--ignore-workspace` keeps each demo a standalone install so it consumes the
// PACKED @kson/monaco-editor (file:), not a workspace symlink to source.
// It also skips pnpm-workspace.yaml, so the hoisted layout is repeated as a flag.
val installDemoVanilla = register<PixiExecTask>("npm_install_demoVanilla") {
command=listOf("pnpm", "install", "--frozen-lockfile", "--ignore-workspace", "--config.node-linker=hoisted")
command=listOf("pnpm", "install", "--no-frozen-lockfile", "--ignore-workspace", "--config.node-linker=hoisted")
workingDirectory.set(demoVanillaDir)
doNotTrackState("pnpm already tracks its own state")
dependsOn(buildMonaco)
Expand All @@ -94,7 +97,7 @@ tasks {
}

val installDemoIframe = register<PixiExecTask>("npm_install_demoIframe") {
command=listOf("pnpm", "install", "--frozen-lockfile", "--ignore-workspace", "--config.node-linker=hoisted")
command=listOf("pnpm", "install", "--no-frozen-lockfile", "--ignore-workspace", "--config.node-linker=hoisted")
workingDirectory.set(demoIframeDir)
doNotTrackState("pnpm already tracks its own state")
dependsOn(buildMonaco)
Expand All @@ -108,7 +111,7 @@ tasks {
}

val installDemoReact = register<PixiExecTask>("npm_install_demoReact") {
command=listOf("pnpm", "install", "--frozen-lockfile", "--ignore-workspace", "--config.node-linker=hoisted")
command=listOf("pnpm", "install", "--no-frozen-lockfile", "--ignore-workspace", "--config.node-linker=hoisted")
workingDirectory.set(demoReactDir)
doNotTrackState("pnpm already tracks its own state")
dependsOn(buildMonaco)
Expand All @@ -124,7 +127,7 @@ tasks {
val demosDir = layout.projectDirectory.dir("demos")

val installTestDemos = register<PixiExecTask>("npm_install_testDemos") {
command=listOf("pnpm", "install", "--frozen-lockfile", "--ignore-workspace", "--config.node-linker=hoisted")
command=listOf("pnpm", "install", "--no-frozen-lockfile", "--ignore-workspace", "--config.node-linker=hoisted")
workingDirectory.set(demosDir)
doNotTrackState("pnpm already tracks its own state")
dependsOn(buildMonaco)
Expand Down
Loading