Generate workspace.json for kotlin-lsp from Gradle builds.
Targets repositories where the default kotlin-lsp project import does not work -- when the build runs through a wrapper around Gradle, or when dependencies come from custom package or cache layouts.
# Homebrew (macOS / Linux)
brew install Unril/tap/klspw
# From source
brew install cmake ninja just
export VCPKG_ROOT="$HOME/vcpkg"
just check # configure + build + test
just install # release build + install to /usr/localcd my-project
klspw -c . init -d ./ # discover Gradle roots, write klspw.yaml
klspw generate # run Gradle, write workspace.jsonOpen the folder in VS Code or Kiro with the kotlin-lsp extension installed. kotlin-lsp detects workspace.json and imports the workspace.
# Generate a starter config (-c . writes to ./klspw.yaml; without -c, prints to stdout)
klspw -c . init ./my-project # explicit root
klspw -c . init -d ./src # discover roots under ./src
klspw -c . init "./proj gradlew" # custom build command
klspw -c . init ./proj_1 ./proj_2 -b cmd # multiple roots, global build
# Run Gradle and write workspace.json (reads ./klspw.yaml by default)
klspw generate
klspw -c config.yaml generate # explicit config path
# Inspect discovered modules and libraries without writing
klspw inspect
# Validate config paths and build commands
klspw validate
# Save raw Gradle output for debugging
klspw generate --save-gradle-output output.txt
klspw inspect --save-gradle-output output.txt # also works on inspect
# Verbose logging
klspw --log-level debug generateConfig file (default name: klspw.yaml):
version: 1
workspace_file: ./workspace.json
jvm_target: "21"
build:
command: ["./gradlew"]
gradle_args: ["--quiet"]
roots:
- path: ./src/my-service
- path: ./src/other-service
build:
command: ["gradle"]
gradle_args: ["--no-daemon"]
options:
include_tests: true
attach_sources: true
remove_missing_paths: truebuildsets the default Gradle command for all roots- Each root can override
buildwith its owncommandandgradle_args - Paths resolve relative to the config file directory
include_testscontrols whether test source sets appear in the workspace (default: true)attach_sourcesdiscovers and attaches source jars to libraries via Gradle-resolved mappings and package cache layouts (default: true)remove_missing_pathswarns and removes source roots and classpath jars that don't exist on disk (default: true)
- Read config, validate paths
- For each root, run the configured Gradle command with a temporary init script
- The init script dumps project metadata as JSON between
KLSPW_BEGIN/KLSPW_ENDdelimiters, including Gradle-resolved source jar mappings, classpath coordinates (Mavengroup:module:versionfor each jar), and compiler plugin classpaths - Parse source sets, classpaths, and project structure from the JSON output
- Name libraries using Maven coordinates (from classpath coordinates or Gradle cache paths) to avoid collisions in KMP projects where multiple libraries produce identically-named jars
- For Android projects, pick one build variant (debug) to avoid class redeclaration errors from variant-specific source directories; include the R class jar from build intermediates so
R.layout.*,R.string.*, etc. resolve correctly - Attach source jars to libraries (from Gradle resolution, filesystem discovery, then coordinate-based cache search as fallback)
- Convert to kotlin-lsp workspace model (modules, libraries, kotlin settings with compiler plugin classpaths)
- Merge results across roots, deduplicating libraries by name
- Promote library dependencies to module dependencies when a library matches a workspace module (sibling Gradle root)
- For KMP projects, inject a kotlin-native-stubs.jar providing JVM stubs for
kotlin.native.*annotations that only exist in Kotlin/Native metadata - Write deterministic, pretty-printed
workspace.json
kotlin-lsp provides Kotlin language support (completion, diagnostics, navigation, refactoring) for VS Code and Kiro. It normally imports Gradle projects automatically, but that fails when the build runs through a wrapper or dependencies come from non-standard locations. klspw bridges this gap by generating a workspace.json that kotlin-lsp can import directly.
Prerequisites: Java 17+ on PATH.
-
Install the kotlin-lsp extension: download the latest
.vsixfrom the kotlin-lsp releases page, then install it via Extensions >...> Install from VSIX. The extension bundles the language server. -
Create a klspw config in your Kotlin project root:
klspw -c . init ./my-projectEdit
klspw.yamlif needed (build command, extra roots, options). -
Generate the workspace:
klspw generate
This writes
workspace.jsonnext toklspw.yaml. -
Open the project folder in VS Code or Kiro. kotlin-lsp detects
workspace.jsonand uses it for project import instead of running Gradle itself. -
If you change dependencies or project structure, re-run
klspw generateand restart the language server with theKotlin LSP: Restartcommand from the command palette.
To verify the import worked, check the kotlin-lsp output panel for messages about loaded modules and libraries.
include/ # Public headers (header-only logic + declarations)
src/ # CLI entry point and .cpp implementations
test/ # Unit and integration tests (doctest)
fixtures/ # Test data (YAML configs, Gradle projects)
resources/ # Gradle init script, CMake templates, and KMP stub jars
fuzz/ # libFuzzer fuzz targets
scripts/ # Utility scripts
See CONTRIBUTING.md for build instructions, dependencies, CI, and release process.