Build Server Protocol
This document is the specification of the Build Server Protocol (BSP).
Edits to this specification can be made via a pull request against this markdown document, see "edit" button at the bottom of this page on the website.
Motivation
The goal of BSP is to reduce the effort required by tooling developers to integrate between available IDEs and build tools. Currently, every IDE must implement a custom integration for each supported build tool in order to extract information such as source directory layouts or compiler options. Likewise, new build tools are expected to integrate with all available IDEs. The growing number of IDEs and build tools in the wider programming community means tooling developers spend a lot of time working on these integrations.
The Build Server Protocol defines common functionality that both build tools (servers) and IDEs (clients) understand. This common functionality enables tooling developers to provide their end users the best developer experience while supporting build tools and language servers with less effort and time.
Background
The Build Server Protocol takes inspiration from the Language Server Protocol (LSP). Unlike in the Language Server Protocol, the language server or IDE is referred to as the “client” and a build tool such as sbt/Gradle/Bazel is referred to as the “server”.
The best way to read this document is by considering it as a wishlist from the perspective of an IDE developer.
The code listings in this document are written using TypeScript syntax. Every data strucuture in this document has a direct translation to JSON and Protobuf.
Relationship with LSP
BSP can be used together with LSP in the same architecture. The diagram below illustrates an example how an LSP server can also act as a BSP client.
BSP can also be used without LSP. In the example above, IntelliJ acts as a BSP client even if IntelliJ does not use LSP.
Status
The Build Server Protocol is not an approved standard. Everything in this document is subject to change and open for discussions, including core data structures.
The creation of BSP clients and servers is under active development.
In the clients space, IntelliJ has been the first language server to implement BSP. The integration is available in the nightly releases of the Scala plugin. Other language servers, like Dotty IDE and scalameta/metals, are currently working or planning to work on a BSP integrations.
On the server side,
- Bloop was the first server to implement BSP
- sbt added built-in support in 1.4.0,
- Mill ships with built-in BSP support
- Bazel support is provided by bazel-bsp
We're looking for third parties that implement BSP natively in other build tools such as Gradle.
The Build Server Protocol has been designed to be language-agnostic. We're looking for ways to collaborate with other programming language communities and build tool authors.
The best way to share your thoughts on the Build Server Protocol or to get involved in its development is to open an issue or pull request to this repository. Any help on developing integrations will be much appreciated.
Base protocol
The base protocol is identical to the language server base protocol. See https://microsoft.github.io/language-server-protocol/specification for more details.
Like the language server protocol, the build server protocol defines a set of JSON-RPC request, response and notification messages which are exchanged using the base protocol.
Capabilities
Unlike the language server protocol, the build server protocol does not support dynamic registration of capabilities. The motivation for this change is simplicity. If a motivating example for dynamic registration comes up this decision can be reconsidered. The server and client capabilities must be communicated through the initialize request.
Server lifetime
Like the language server protocol, the current protocol specification defines that the lifetime of a build server is managed by the client (e.g. a language server like Dotty IDE). It is up to the client to decide when to start (process-wise) and when to shutdown a server.
BSP version
2.2.0
Common shapes
Integer
An integer is a 32-bit signed integer ranging from -2^31 to (2^31)-1 (inclusive).
export type Integer = number;
Long
A long is a 64-bit signed integer ranging from -2^63 to (2^63)-1 (inclusive).
export type Long = number;
BuildTarget
Build target contains metadata about an artifact (for example library, test, or binary artifact). Using vocabulary of other build tools:
- sbt: a build target is a combined project + config. Example:
- a regular JVM project with main and test configurations will have 2 build targets, one for main and one for test.
- a single configuration in a single project that contains both Java and Scala sources maps to one BuildTarget.
- a project with crossScalaVersions 2.11 and 2.12 containing main and test configuration in each will have 4 build targets.
- a Scala 2.11 and 2.12 cross-built project for Scala.js and the JVM with main and test configurations will have 8 build targets.
- Pants: a pants target corresponds one-to-one with a BuildTarget
- Bazel: a bazel target corresponds one-to-one with a BuildTarget
The general idea is that the BuildTarget data structure should contain only information that is fast or cheap to compute.
export interface BuildTarget {
/** The target's unique identifier */
id: BuildTargetIdentifier;
/** A human readable name for this target.
* May be presented in the user interface.
* Should be unique if possible.
* The id.uri is used if None. */
displayName?: string;
/** The directory where this target belongs to. Multiple build targets are allowed to map
* to the same base directory, and a build target is not required to have a base directory.
* A base directory does not determine the sources of a target, see buildTarget/sources. */
baseDirectory?: URI;
/** Free-form string tags to categorize or label this build target.
* For example, can be used by the client to:
* - customize how the target should be translated into the client's project model.
* - group together different but related targets in the user interface.
* - display icons or colors in the user interface.
* Pre-defined tags are listed in `BuildTargetTag` but clients and servers
* are free to define new tags for custom purposes. */
tags: BuildTargetTag[];
/** The set of languages that this target contains.
* The ID string for each language is defined in the LSP. */
languageIds: LanguageId[];
/** The direct upstream build target dependencies of this build target */
dependencies: BuildTargetIdentifier[];
/** The capabilities of this build target. */
capabilities: BuildTargetCapabilities;
/** Kind of data to expect in the `data` field. If this field is not set, the kind of data is not specified. */
dataKind?: BuildTargetDataKind;
/** Language-specific metadata about this target.
* See ScalaBuildTarget as an example. */
data?: BuildTargetData;
}
BuildTargetIdentifier
A unique identifier for a target, can use any URI-compatible encoding as long as it is unique within the workspace.
Clients should not infer metadata out of the URI structure such as the path or query parameters, use BuildTarget
instead.
export interface BuildTargetIdentifier {
/** The target's Uri */
uri: URI;
}
URI
A resource identifier that is a valid URI according to rfc3986: https://tools.ietf.org/html/rfc3986
export type URI = string;
BuildTargetTag
A list of predefined tags that can be used to categorize build targets.
export type BuildTargetTag = string;
export namespace BuildTargetTag {
/** Target contains source code for producing any kind of application, may have
* but does not require the `canRun` capability. */
export const Application = "application";
/** Target contains source code to measure performance of a program, may have
* but does not require the `canRun` build target capability. */
export const Benchmark = "benchmark";
/** Target contains source code for integration testing purposes, may have
* but does not require the `canTest` capability.
* The difference between "test" and "integration-test" is that
* integration tests traditionally run slower compared to normal tests
* and require more computing resources to execute. */
export const IntegrationTest = "integration-test";
/** Target contains re-usable functionality for downstream targets. May have any
* combination of capabilities. */
export const Library = "library";
/** Actions on the target such as build and test should only be invoked manually
* and explicitly. For example, triggering a build on all targets in the workspace
* should by default not include this target.
* The original motivation to add the "manual" tag comes from a similar functionality
* that exists in Bazel, where targets with this tag have to be specified explicitly
* on the command line. */
export const Manual = "manual";
/** Target should be ignored by IDEs. */
export const NoIde = "no-ide";
/** Target contains source code for testing purposes, may have but does not
* require the `canTest` capability. */
export const Test = "test";
}
LanguageId
Language IDs are defined here https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocumentItem
export type LanguageId = string;
BuildTargetCapabilities
Clients can use these capabilities to notify users what BSP endpoints can and cannot be used and why.
export interface BuildTargetCapabilities {
/** This target can be compiled by the BSP server. */
canCompile?: boolean;
/** This target can be tested by the BSP server. */
canTest?: boolean;
/** This target can be run by the BSP server. */
canRun?: boolean;
/** This target can be debugged by the BSP server. */
canDebug?: boolean;
}
BuildTargetDataKind
export type BuildTargetDataKind = string;
export namespace BuildTargetDataKind {
/** `data` field must contain a CargoBuildTarget object. */
export const Cargo = "cargo";
/** `data` field must contain a CppBuildTarget object. */
export const Cpp = "cpp";
/** `data` field must contain a JvmBuildTarget object. */
export const Jvm = "jvm";
/** `data` field must contain a PythonBuildTarget object. */
export const Python = "python";
/** `data` field must contain a SbtBuildTarget object. */
export const Sbt = "sbt";
/** `data` field must contain a ScalaBuildTarget object. */
export const Scala = "scala";
}
BuildTargetData
export type BuildTargetData = any;
OriginId
Represents the identifier of a BSP request.
export type OriginId = string;
TaskId
The Task Id allows clients to uniquely identify a BSP task and establish a client-parent relationship with another task id.
export interface TaskId {
/** A unique identifier */
id: Identifier;
/** The parent task ids, if any. A non-empty parents field means
* this task is a sub-task of every parent task id. The child-parent
* relationship of tasks makes it possible to render tasks in
* a tree-like user interface or inspect what caused a certain task
* execution.
* OriginId should not be included in the parents field, there is a separate
* field for that. */
parents?: Identifier[];
}
Identifier
export type Identifier = string;
StatusCode
Included in notifications of tasks or requests to signal the completion state.
export enum StatusCode {
/** Execution was successful. */
Ok = 1,
/** Execution failed. */
Error = 2,
/** Execution was cancelled. */
Cancelled = 3,
}
EnvironmentVariables
export type EnvironmentVariables = Map<string, string>;
BSP Server remote interface
BuildInitialize: request
Like the language server protocol, the initialize request is sent as the first request from the client to the server. If the server receives a request or notification before the initialize request it should act as follows:
- For a request the response should be an error with code: -32002. The message can be picked by the server.
- Notifications should be dropped, except for the exit notification. This will allow the exit of a server without an initialize request.
Until the server has responded to the initialize request with an InitializeBuildResult, the client must not send any additional requests or notifications to the server.
- method:
build/initialize
- params:
InitializeBuildParams
- result:
InitializeBuildResult
InitializeBuildParams
export interface InitializeBuildParams {
/** Name of the client */
displayName: string;
/** The version of the client */
version: string;
/** The BSP version that the client speaks */
bspVersion: string;
/** The rootUri of the workspace */
rootUri: URI;
/** The capabilities of the client */
capabilities: BuildClientCapabilities;
/** Kind of data to expect in the `data` field. If this field is not set, the kind of data is not specified. */
dataKind?: InitializeBuildParamsDataKind;
/** Additional metadata about the client */
data?: InitializeBuildParamsData;
}
BuildClientCapabilities
export interface BuildClientCapabilities {
/** The languages that this client supports.
* The ID strings for each language is defined in the LSP.
* The server must never respond with build targets for other
* languages than those that appear in this list. */
languageIds: LanguageId[];
/** Mirror capability to BuildServerCapabilities.jvmCompileClasspathProvider
* The client will request classpath via `buildTarget/jvmCompileClasspath` so
* it's safe to return classpath in ScalacOptionsItem empty. */
jvmCompileClasspathReceiver?: boolean;
}
InitializeBuildParamsDataKind
export type InitializeBuildParamsDataKind = string;
export namespace InitializeBuildParamsDataKind {}
InitializeBuildParamsData
export type InitializeBuildParamsData = any;
InitializeBuildResult
export interface InitializeBuildResult {
/** Name of the server */
displayName: string;
/** The version of the server */
version: string;
/** The BSP version that the server speaks */
bspVersion: string;
/** The capabilities of the build server */
capabilities: BuildServerCapabilities;
/** Kind of data to expect in the `data` field. If this field is not set, the kind of data is not specified. */
dataKind?: InitializeBuildResultDataKind;
/** Additional metadata about the server */
data?: InitializeBuildResultData;
}
BuildServerCapabilities
The capabilities of the build server. Clients can use these capabilities to notify users what BSP endpoints can and cannot be used and why.
export interface BuildServerCapabilities {
/** The languages the server supports compilation via method buildTarget/compile. */
compileProvider?: CompileProvider;
/** The languages the server supports test execution via method buildTarget/test. */
testProvider?: TestProvider;
/** The languages the server supports run via method buildTarget/run. */
runProvider?: RunProvider;
/** The languages the server supports debugging via method debugSession/start. */
debugProvider?: DebugProvider;
/** The server can provide a list of targets that contain a
* single text document via the method buildTarget/inverseSources */
inverseSourcesProvider?: boolean;
/** The server provides sources for library dependencies
* via method buildTarget/dependencySources */
dependencySourcesProvider?: boolean;
/** The server can provide a list of dependency modules (libraries with meta information)
* via method buildTarget/dependencyModules */
dependencyModulesProvider?: boolean;
/** The server provides all the resource dependencies
* via method buildTarget/resources */
resourcesProvider?: boolean;
/** The server provides all output paths
* via method buildTarget/outputPaths */
outputPathsProvider?: boolean;
/** The server sends notifications to the client on build
* target change events via buildTarget/didChange */
buildTargetChangedProvider?: boolean;
/** The server can respond to `buildTarget/jvmRunEnvironment` requests with the
* necessary information required to launch a Java process to run a main class. */
jvmRunEnvironmentProvider?: boolean;
/** The server can respond to `buildTarget/jvmTestEnvironment` requests with the
* necessary information required to launch a Java process for testing or
* debugging. */
jvmTestEnvironmentProvider?: boolean;
/** The server can respond to `workspace/cargoFeaturesState` and
* `setCargoFeatures` requests. In other words, supports Cargo Features extension. */
cargoFeaturesProvider?: boolean;
/** Reloading the build state through workspace/reload is supported */
canReload?: boolean;
/** The server can respond to `buildTarget/jvmCompileClasspath` requests with the
* necessary information about the target's classpath. */
jvmCompileClasspathProvider?: boolean;
}
CompileProvider
export interface CompileProvider {
languageIds: LanguageId[];
}
TestProvider
export interface TestProvider {
languageIds: LanguageId[];
}
RunProvider
export interface RunProvider {
languageIds: LanguageId[];
}
DebugProvider
export interface DebugProvider {
languageIds: LanguageId[];
}
InitializeBuildResultDataKind
export type InitializeBuildResultDataKind = string;
export namespace InitializeBuildResultDataKind {}
InitializeBuildResultData
export type InitializeBuildResultData = any;
OnBuildInitialized: notification
Like the language server protocol, the initialized notification is sent from the client to the server after the client received the result of the initialize request but before the client is sending any other request or notification to the server. The server can use the initialized notification for example to initialize intensive computation such as dependency resolution or compilation. The initialized notification may only be sent once.
- method:
build/initialized
BuildShutdown: request
Like the language server protocol, the shutdown build request is sent from the client to the server. It asks the server to shut down, but to not exit (otherwise the response might not be delivered correctly to the client). There is a separate exit notification that asks the server to exit.
- method:
build/shutdown
OnBuildExit: notification
Like the language server protocol, a notification to ask the server to exit its process. The server should exit with success code 0 if the shutdown request has been received before; otherwise with error code 1.
- method:
build/exit
WorkspaceBuildTargets: request
The workspace build targets request is sent from the client to the server to ask for the list of all available build targets in the workspace.
- method:
workspace/buildTargets
- result:
WorkspaceBuildTargetsResult
WorkspaceBuildTargetsResult
export interface WorkspaceBuildTargetsResult {
/** The build targets in this workspace that
* contain sources with the given language ids. */
targets: BuildTarget[];
}
WorkspaceReload: request
The reload
request is sent from the client to instruct the build server to reload
the build configuration. This request should be supported by build tools that keep
their state in memory. If the reload
request returns with an error, it's expected
that other requests respond with the previously known "good" state.
- method:
workspace/reload
BuildTargetSources: request
The build target sources request is sent from the client to the server to query
for the list of text documents and directories that are belong to a build
target. The sources response must not include sources that are external to the
workspace, see buildTarget/dependencySources
.
- method:
buildTarget/sources
- params:
SourcesParams
- result:
SourcesResult
SourcesParams
export interface SourcesParams {
targets: BuildTargetIdentifier[];
}
SourcesResult
export interface SourcesResult {
items: SourcesItem[];
}
SourcesItem
export interface SourcesItem {
target: BuildTargetIdentifier;
/** The text documents or and directories that belong to this build target. */
sources: SourceItem[];
/** The root directories from where source files should be relativized.
* Example: ["file://Users/name/dev/metals/src/main/scala"] */
roots?: URI[];
}
SourceItem
export interface SourceItem {
/** Either a text document or a directory. A directory entry must end with a forward
* slash "/" and a directory entry implies that every nested text document within the
* directory belongs to this source item. */
uri: URI;
/** Type of file of the source item, such as whether it is file or directory. */
kind: SourceItemKind;
/** Indicates if this source is automatically generated by the build and is not
* intended to be manually edited by the user. */
generated: boolean;
/** Kind of data to expect in the `data` field. If this field is not set, the kind of data is not specified. */
dataKind?: SourceItemDataKind;
/** Language-specific metadata about this source item. */
data?: SourceItemData;
}
SourceItemKind
export enum SourceItemKind {
/** The source item references a normal file. */
File = 1,
/** The source item references a directory. */
Directory = 2,
}
SourceItemDataKind
export type SourceItemDataKind = string;
export namespace SourceItemDataKind {
/** `data` field must contain a JvmSourceItemData object. */
export const Jvm = "jvm";
}
SourceItemData
export type SourceItemData = any;
BuildTargetInverseSources: request
The inverse sources request is sent from the client to the server to query for
the list of build targets containing a text document. The server communicates
during the initialize handshake whether this method is supported or not. This
request can be viewed as the inverse of buildTarget/sources
, except it only
works for text documents and not directories.
- method:
buildTarget/inverseSources
- params:
InverseSourcesParams
- result:
InverseSourcesResult
InverseSourcesParams
export interface InverseSourcesParams {
textDocument: TextDocumentIdentifier;
}
TextDocumentIdentifier
export interface TextDocumentIdentifier {
/** The text document's URI. */
uri: URI;
}
InverseSourcesResult
export interface InverseSourcesResult {
targets: BuildTargetIdentifier[];
}
BuildTargetDependencySources: request
The build target dependency sources request is sent from the client to the
server to query for the sources of build target dependencies that are external
to the workspace. The dependency sources response must not include source files
that belong to a build target within the workspace, see buildTarget/sources
.
The server communicates during the initialize handshake whether this method is
supported or not. This method can for example be used by a language server on
textDocument/definition
to "Go to definition" from project sources to
dependency sources.
- method:
buildTarget/dependencySources
- params:
DependencySourcesParams
- result:
DependencySourcesResult
DependencySourcesParams
export interface DependencySourcesParams {
targets: BuildTargetIdentifier[];
}
DependencySourcesResult
export interface DependencySourcesResult {
items: DependencySourcesItem[];
}
DependencySourcesItem
export interface DependencySourcesItem {
target: BuildTargetIdentifier;
/** List of resources containing source files of the
* target's dependencies.
* Can be source files, jar files, zip files, or directories. */
sources: URI[];
}
BuildTargetDependencyModules: request
The build target dependency modules request is sent from the client to the
server to query for the libraries of build target dependencies that are external
to the workspace including meta information about library and their sources.
It's an extended version of buildTarget/sources
.
- method:
buildTarget/dependencyModules
- params:
DependencyModulesParams
- result:
DependencyModulesResult
DependencyModulesParams
export interface DependencyModulesParams {
targets: BuildTargetIdentifier[];
}
DependencyModulesResult
export interface DependencyModulesResult {
items: DependencyModulesItem[];
}
DependencyModulesItem
export interface DependencyModulesItem {
target: BuildTargetIdentifier;
modules: DependencyModule[];
}
DependencyModule
export interface DependencyModule {
/** Module name */
name: string;
/** Module version */
version: string;
/** Kind of data to expect in the `data` field. If this field is not set, the kind of data is not specified. */
dataKind?: DependencyModuleDataKind;
/** Language-specific metadata about this module.
* See MavenDependencyModule as an example. */
data?: DependencyModuleData;
}
DependencyModuleDataKind
export type DependencyModuleDataKind = string;
export namespace DependencyModuleDataKind {
/** `data` field must contain a MavenDependencyModule object. */
export const Maven = "maven";
}
DependencyModuleData
export type DependencyModuleData = any;
BuildTargetResources: request
The build target resources request is sent from the client to the server to query for the list of resources of a given list of build targets.
A resource is a data dependency required to be present in the runtime classpath when a build target is run or executed. The server communicates during the initialize handshake whether this method is supported or not.
This request can be used by a client to highlight the resources in a project view, for example.
- method:
buildTarget/resources
- params:
ResourcesParams
- result:
ResourcesResult
ResourcesParams
export interface ResourcesParams {
targets: BuildTargetIdentifier[];
}
ResourcesResult
export interface ResourcesResult {
items: ResourcesItem[];
}
ResourcesItem
export interface ResourcesItem {
target: BuildTargetIdentifier;
/** List of resource files. */
resources: URI[];
}
BuildTargetOutputPaths: request
The build target output paths request is sent from the client to the server to query for the list of output paths of a given list of build targets.
An output path is a file or directory that contains output files such as build artifacts which IDEs may decide to exclude from indexing. The server communicates during the initialize handshake whether this method is supported or not.
- method:
buildTarget/outputPaths
- params:
OutputPathsParams
- result:
OutputPathsResult
OutputPathsParams
export interface OutputPathsParams {
targets: BuildTargetIdentifier[];
}
OutputPathsResult
export interface OutputPathsResult {
items: OutputPathsItem[];
}
OutputPathsItem
export interface OutputPathsItem {
/** A build target to which output paths item belongs. */
target: BuildTargetIdentifier;
/** Output paths. */
outputPaths: OutputPathItem[];
}
OutputPathItem
export interface OutputPathItem {
/** Either a file or a directory. A directory entry must end with a forward
* slash "/" and a directory entry implies that every nested path within the
* directory belongs to this output item. */
uri: URI;
/** Type of file of the output item, such as whether it is file or directory. */
kind: OutputPathItemKind;
}
OutputPathItemKind
export enum OutputPathItemKind {
/** The output path item references a normal file. */
File = 1,
/** The output path item references a directory. */
Directory = 2,
}
BuildTargetCompile: request
The compile build target request is sent from the client to the server to
compile the given list of build targets. The server communicates during the
initialize handshake whether this method is supported or not. This method can
for example be used by a language server before textDocument/rename
to ensure
that all workspace sources typecheck correctly and are up-to-date.
- method:
buildTarget/compile
- params:
CompileParams
- result:
CompileResult
CompileParams
export interface CompileParams {
/** A sequence of build targets to compile. */
targets: BuildTargetIdentifier[];
/** A unique identifier generated by the client to identify this request.
* The server may include this id in triggered notifications or responses. */
originId?: Identifier;
/** Optional arguments to the compilation process. */
arguments?: string[];
}
CompileResult
export interface CompileResult {
/** An optional request id to know the origin of this report. */
originId?: Identifier;
/** A status code for the execution. */
statusCode: StatusCode;
/** Kind of data to expect in the `data` field. If this field is not set, the kind of data is not specified. */
dataKind?: CompileResultDataKind;
/** A field containing language-specific information, like products
* of compilation or compiler-specific metadata the client needs to know. */
data?: CompileResultData;
}
CompileResultDataKind
export type CompileResultDataKind = string;
export namespace CompileResultDataKind {}
CompileResultData
export type CompileResultData = any;
BuildTargetRun: request
The run request is sent from the client to the server to run a build target. The server communicates during the initialize handshake whether this method is supported or not.
Note that a run request containing only the target id is valid. If no further parameters are provided, the server should use the default ones.
Implementation notes:
This request may trigger a compilation on the selected build targets. The server
is free to send any number of build/task*
, build/publishDiagnostics
and
build/logMessage
notifications during compilation before completing the
response.
The client will get a originId
field in RunResult
if and only if
the originId
field in the RunParams
is defined.
Cancelling this request must kill the running process.
If the BSP server wishes to forward the stdout and stderr streams of the running process
to the client, it can do so by sending run/printStdout
and run/printStderr
notifications.
If the client wishes to send input to the running process, it can do so by sending
run/readStdin
notifications to the server.
- method:
buildTarget/run
- params:
RunParams
- result:
RunResult
RunParams
export interface RunParams {
/** The build target to run. */
target: BuildTargetIdentifier;
/** A unique identifier generated by the client to identify this request.
* The server may include this id in triggered notifications or responses. */
originId?: Identifier;
/** Optional arguments to the executed application. */
arguments?: string[];
/** Optional environment variables to set before running the application. */
environmentVariables?: EnvironmentVariables;
/** Optional working directory */
workingDirectory?: URI;
/** Kind of data to expect in the `data` field. If this field is not set, the kind of data is not specified. */
dataKind?: RunParamsDataKind;
/** Language-specific metadata for this execution.
* See ScalaMainClass as an example. */
data?: RunParamsData;
}
RunParamsDataKind
export type RunParamsDataKind = string;
export namespace RunParamsDataKind {
/** `data` field must contain a ScalaMainClass object. */
export const ScalaMainClass = "scala-main-class";
}
RunParamsData
export type RunParamsData = any;
RunResult
export interface RunResult {
/** An optional request id to know the origin of this report. */
originId?: Identifier;
/** A status code for the execution. */
statusCode: StatusCode;
}
BuildTargetTest: request
The test build target request is sent from the client to the server to test the given list of build targets. The server communicates during the initialize handshake whether this method is supported or not.
The "Implementation notes" section of the buildTarget/run
request applies to
this request as well.
- method:
buildTarget/test
- params:
TestParams
- result:
TestResult
TestParams
export interface TestParams {
/** A sequence of build targets to test. */
targets: BuildTargetIdentifier[];
/** A unique identifier generated by the client to identify this request.
* The server may include this id in triggered notifications or responses. */
originId?: Identifier;
/** Optional arguments to the test execution engine. */
arguments?: string[];
/** Optional environment variables to set before running the tests. */
environmentVariables?: EnvironmentVariables;
/** Optional working directory */
workingDirectory?: URI;
/** Kind of data to expect in the `data` field. If this field is not set, the kind of data is not specified. */
dataKind?: TestParamsDataKind;
/** Language-specific metadata about for this test execution.
* See ScalaTestParams as an example. */
data?: TestParamsData;
}
TestParamsDataKind
export type TestParamsDataKind = string;
export namespace TestParamsDataKind {
/** `data` field must contain a ScalaTestParams object. */
export const ScalaTest = "scala-test";
/** `data` field must contain a ScalaTestSuiteClasses object. */
export const ScalaTestSuites = "scala-test-suites";
/** `data` field must contain a ScalaTestSuites object. */
export const ScalaTestSuitesSelection = "scala-test-suites-selection";
}
TestParamsData
export type TestParamsData = any;
TestResult
export interface TestResult {
/** An optional request id to know the origin of this report. */
originId?: Identifier;
/** A status code for the execution. */
statusCode: StatusCode;
/** Kind of data to expect in the `data` field. If this field is not set, the kind of data is not specified. */
dataKind?: TestResultDataKind;
/** Language-specific metadata about the test result.
* See ScalaTestParams as an example. */
data?: TestResultData;
}
TestResultDataKind
export type TestResultDataKind = string;
export namespace TestResultDataKind {}
TestResultData
export type TestResultData = any;
DebugSessionStart: request
The debug request is sent from the client to the server to debug build target(s). The server launches a Microsoft DAP server and returns a connection URI for the client to interact with.
- method:
debugSession/start
- params:
DebugSessionParams
- result:
DebugSessionAddress
DebugSessionParams
export interface DebugSessionParams {
/** A sequence of build targets affected by the debugging action. */
targets: BuildTargetIdentifier[];
/** Kind of data to expect in the `data` field. If this field is not set, the kind of data is not specified. */
dataKind?: DebugSessionParamsDataKind;
/** Language-specific metadata for this execution.
* See ScalaMainClass as an example. */
data?: DebugSessionParamsData;
}
DebugSessionParamsDataKind
export type DebugSessionParamsDataKind = string;
export namespace DebugSessionParamsDataKind {
/** `data` field must contain a ScalaAttachRemote object. */
export const ScalaAttachRemote = "scala-attach-remote";
/** `data` field must contain a ScalaMainClass object. */
export const ScalaMainClass = "scala-main-class";
}
DebugSessionParamsData
export type DebugSessionParamsData = any;
DebugSessionAddress
export interface DebugSessionAddress {
/** The Debug Adapter Protocol server's connection uri */
uri: URI;
}
BuildTargetCleanCache: request
The clean cache request is sent from the client to the server to reset any state associated with a given build target. The state can live either in the build tool or in the file system.
The build tool defines the exact semantics of the clean cache request:
- Stateless build tools are free to ignore the request and respond with a successful response.
- Stateful build tools must ensure that invoking compilation on a target that has been cleaned results in a full compilation.
- method:
buildTarget/cleanCache
- params:
CleanCacheParams
- result:
CleanCacheResult
CleanCacheParams
export interface CleanCacheParams {
/** The build targets to clean. */
targets: BuildTargetIdentifier[];
}
CleanCacheResult
export interface CleanCacheResult {
/** Optional message to display to the user. */
message?: string;
/** Indicates whether the clean cache request was performed or not. */
cleaned: boolean;
}
OnRunReadStdin: notification
Unstable (may change in future versions)
Notification sent from the client to the server when the user wants to send input to the stdin of the running target.
- method:
run/readStdin
- params:
ReadParams
ReadParams
Unstable (may change in future versions)
export interface ReadParams {
/** The id of the request. */
originId: Identifier;
/** Relevant only for test tasks.
* Allows to tell the client from which task the output is coming from. */
task?: TaskId;
/** Message content can contain arbitrary bytes.
* They should be escaped as per [javascript encoding](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Grammar_and_types#using_special_characters_in_strings) */
message: string;
}
BSP Client remote interface
OnBuildShowMessage: notification
The show message notification is sent from a server to a client to ask the client to display a particular message in the user interface.
A build/showMessage notification is similar to LSP's window/showMessage, except for a few additions like id and originId.
- method:
build/showMessage
- params:
ShowMessageParams
ShowMessageParams
export interface ShowMessageParams {
/** the message type. */
type: MessageType;
/** The task id if any. */
task?: TaskId;
/** The request id that originated this notification.
* The originId field helps clients know which request originated a notification in case several requests are handled by the
* client at the same time. It will only be populated if the client defined it in the request that triggered this notification. */
originId?: OriginId;
/** The actual message. */
message: string;
}
MessageType
export enum MessageType {
/** An error message. */
Error = 1,
/** A warning message. */
Warning = 2,
/** An information message. */
Info = 3,
/** A log message. */
Log = 4,
}
OnBuildLogMessage: notification
The log message notification is sent from a server to a client to ask the client to log a particular message in its console.
A build/logMessage notification is similar to LSP's window/logMessage, except for a few additions like id and originId.
- method:
build/logMessage
- params:
LogMessageParams
LogMessageParams
export interface LogMessageParams {
/** the message type. */
type: MessageType;
/** The task id if any. */
task?: TaskId;
/** The request id that originated this notification.
* The originId field helps clients know which request originated a notification in case several requests are handled by the
* client at the same time. It will only be populated if the client defined it in the request that triggered this notification. */
originId?: OriginId;
/** The actual message. */
message: string;
}
OnBuildPublishDiagnostics: notification
The Diagnostics notification are sent from the server to the client to signal results of validation runs.
When reset is true, the client must clean all previous diagnostics associated with the same textDocument and buildTarget and set instead the diagnostics in the request. This is the same behaviour as PublishDiagnosticsParams in the LSP. When reset is false, the diagnostics are added to the last active diagnostics, allowing build tools to stream diagnostics to the client.
It is the server's responsibility to manage the lifetime of the diagnostics by using the appropriate value in the reset field. Clients generate new diagnostics by calling any BSP endpoint that triggers a buildTarget/compile, such as buildTarget/compile, buildTarget/test and buildTarget/run.
If the computed set of diagnostic is empty, the server must push an empty array with reset set to true, in order to clear previous diagnostics.
The optional originId field in the definition of PublishDiagnosticsParams can be used by clients to know which request originated the notification. This field will be defined if the client defined it in the original request that triggered this notification.
- method:
build/publishDiagnostics
- params:
PublishDiagnosticsParams
PublishDiagnosticsParams
export interface PublishDiagnosticsParams {
/** The document where the diagnostics are published. */
textDocument: TextDocumentIdentifier;
/** The build target where the diagnostics origin.
* It is valid for one text document to belong to multiple
* build targets, for example sources that are compiled against multiple
* platforms (JVM, JavaScript). */
buildTarget: BuildTargetIdentifier;
/** The request id that originated this notification. */
originId?: OriginId;
/** The diagnostics to be published by the client. */
diagnostics: Diagnostic[];
/** Whether the client should clear the previous diagnostics
* mapped to the same `textDocument` and `buildTarget`. */
reset: boolean;
}
Diagnostic
Diagnostic is defined as it is in the LSP.
export interface Diagnostic {
/** The range at which the message applies. */
range: Range;
/** The diagnostic's severity. Can be omitted. If omitted it is up to the
* client to interpret diagnostics as error, warning, info or hint. */
severity?: DiagnosticSeverity;
/** The diagnostic's code, which might appear in the user interface. */
code?: string | Integer;
/** An optional property to describe the error code. */
codeDescription?: CodeDescription;
/** A human-readable string describing the source of this
* diagnostic, e.g. 'typescript' or 'super lint'. */
source?: string;
/** The diagnostic's message. */
message: string;
/** Additional metadata about the diagnostic. */
tags?: DiagnosticTag[];
/** An array of related diagnostic information, e.g. when symbol-names within
* a scope collide all definitions can be marked via this property. */
relatedInformation?: DiagnosticRelatedInformation[];
/** Kind of data to expect in the `data` field. If this field is not set, the kind of data is not specified. */
dataKind?: DiagnosticDataKind;
/** A data entry field that is preserved between a
* `textDocument/publishDiagnostics` notification and
* `textDocument/codeAction` request. */
data?: DiagnosticData;
}
Range
export interface Range {
/** The range's start position. */
start: Position;
/** The range's end position. */
end: Position;
}
Position
export interface Position {
/** Line position in a document (zero-based). */
line: Integer;
/** Character offset on a line in a document (zero-based)
*
* If the character value is greater than the line length it defaults back
* to the line length. */
character: Integer;
}
DiagnosticSeverity
export enum DiagnosticSeverity {
/** Reports an error. */
Error = 1,
/** Reports a warning. */
Warning = 2,
/** Reports an information. */
Information = 3,
/** Reports a hint. */
Hint = 4,
}
CodeDescription
Structure to capture a description for an error code.
export interface CodeDescription {
/** An URI to open with more information about the diagnostic error. */
href: URI;
}
DiagnosticTag
export type DiagnosticTag = number;
export namespace DiagnosticTag {
/** Unused or unnecessary code.
*
* Clients are allowed to render diagnostics with this tag faded out
* instead of having an error squiggle. */
export const Unnecessary = 1;
/** Deprecated or obsolete code.
*
* Clients are allowed to rendered diagnostics with this tag strike through. */
export const Deprecated = 2;
}
DiagnosticRelatedInformation
Represents a related message and source code location for a diagnostic. This should be used to point to code locations that cause or are related to a diagnostics, e.g when duplicating a symbol in a scope.
export interface DiagnosticRelatedInformation {
/** The location of this related diagnostic information. */
location: Location;
/** The message of this related diagnostic information. */
message: string;
}
Location
export interface Location {
uri: URI;
range: Range;
}
DiagnosticDataKind
export type DiagnosticDataKind = string;
export namespace DiagnosticDataKind {
/** `data` field must contain a ScalaDiagnostic object. */
export const Scala = "scala";
}
DiagnosticData
export type DiagnosticData = any;
OnBuildTargetDidChange: notification
The build target changed notification is sent from the server to the client to signal a change in a build target. The server communicates during the initialize handshake whether this method is supported or not.
- method:
buildTarget/didChange
- params:
DidChangeBuildTarget
DidChangeBuildTarget
export interface DidChangeBuildTarget {
changes: BuildTargetEvent[];
}
BuildTargetEvent
export interface BuildTargetEvent {
/** The identifier for the changed build target */
target: BuildTargetIdentifier;
/** The kind of change for this build target */
kind?: BuildTargetEventKind;
/** Kind of data to expect in the `data` field. If this field is not set, the kind of data is not specified. */
dataKind?: BuildTargetEventDataKind;
/** Any additional metadata about what information changed. */
data?: BuildTargetEventData;
}
BuildTargetEventKind
The BuildTargetEventKind
information can be used by clients to trigger
reindexing or update the user interface with the new information.
export enum BuildTargetEventKind {
/** The build target is new. */
Created = 1,
/** The build target has changed. */
Changed = 2,
/** The build target has been deleted. */
Deleted = 3,
}
BuildTargetEventDataKind
export type BuildTargetEventDataKind = string;
export namespace BuildTargetEventDataKind {}
BuildTargetEventData
export type BuildTargetEventData = any;
OnBuildTaskStart: notification
The BSP server can inform the client on the execution state of any task in the build tool. The execution of some tasks, such as compilation or tests, must always be reported by the server.
The server may also send additional task notifications for actions not covered by the protocol, such as resolution or packaging. BSP clients can then display this information to their users at their discretion.
When beginning a task, the server may send build/taskStart
, intermediate
updates may be sent in build/taskProgress
.
If a build/taskStart
notification has been sent, the server must send
build/taskFinish
on completion of the same task.
build/taskStart
, build/taskProgress
and build/taskFinish
notifications for
the same task must use the same taskId
.
Tasks that are spawned by another task should reference the originating task's
taskId
in their own taskId
's parent
field. Tasks spawned directly by a
request should reference the request's originId
parent.
- method:
build/taskStart
- params:
TaskStartParams
TaskStartParams
export interface TaskStartParams {
/** Unique id of the task with optional reference to parent task id */
taskId: TaskId;
/** A unique identifier generated by the client to identify this request. */
originId?: Identifier;
/** Timestamp of when the event started in milliseconds since Epoch. */
eventTime?: Long;
/** Message describing the task. */
message?: string;
/** Kind of data to expect in the `data` field. If this field is not set, the kind of data is not specified. */
dataKind?: TaskStartDataKind;
/** Optional metadata about the task.
* Objects for specific tasks like compile, test, etc are specified in the protocol. */
data?: TaskStartData;
}
TaskStartDataKind
Task start notifications may contain an arbitrary interface in their data
field. The kind of interface that is contained in a notification must be
specified in the dataKind
field.
There are predefined kinds of objects for compile and test tasks, as described in [[bsp#BuildTargetCompile]] and [[bsp#BuildTargetTest]]
export type TaskStartDataKind = string;
export namespace TaskStartDataKind {
/** `data` field must contain a CompileTask object. */
export const CompileTask = "compile-task";
/** `data` field must contain a TestStart object. */
export const TestStart = "test-start";
/** `data` field must contain a TestTask object. */
export const TestTask = "test-task";
}
TaskStartData
export type TaskStartData = any;
OnBuildTaskProgress: notification
After a taskStart
and before taskFinish
for a taskId
, the server may send
any number of progress notifications.
- method:
build/taskProgress
- params:
TaskProgressParams
TaskProgressParams
export interface TaskProgressParams {
/** Unique id of the task with optional reference to parent task id */
taskId: TaskId;
/** A unique identifier generated by the client to identify this request. */
originId?: Identifier;
/** Timestamp of when the event started in milliseconds since Epoch. */
eventTime?: Long;
/** Message describing the task. */
message?: string;
/** If known, total amount of work units in this task. */
total?: Long;
/** If known, completed amount of work units in this task. */
progress?: Long;
/** Name of a work unit. For example, "files" or "tests". May be empty. */
unit?: string;
/** Kind of data to expect in the `data` field. If this field is not set, the kind of data is not specified. */
dataKind?: TaskProgressDataKind;
/** Optional metadata about the task.
* Objects for specific tasks like compile, test, etc are specified in the protocol. */
data?: TaskProgressData;
}
TaskProgressDataKind
Task progress notifications may contain an arbitrary interface in their data
field. The kind of interface that is contained in a notification must be
specified in the dataKind
field.
export type TaskProgressDataKind = string;
export namespace TaskProgressDataKind {}
TaskProgressData
export type TaskProgressData = any;
OnBuildTaskFinish: notification
A build/taskFinish
notification must always be sent after a build/taskStart
with the same taskId
was sent.
- method:
build/taskFinish
- params:
TaskFinishParams
TaskFinishParams
export interface TaskFinishParams {
/** Unique id of the task with optional reference to parent task id */
taskId: TaskId;
/** A unique identifier generated by the client to identify this request. */
originId?: Identifier;
/** Timestamp of when the event started in milliseconds since Epoch. */
eventTime?: Long;
/** Message describing the task. */
message?: string;
/** Task completion status. */
status: StatusCode;
/** Kind of data to expect in the `data` field. If this field is not set, the kind of data is not specified. */
dataKind?: TaskFinishDataKind;
/** Optional metadata about the task.
* Objects for specific tasks like compile, test, etc are specified in the protocol. */
data?: TaskFinishData;
}
TaskFinishDataKind
Task finish notifications may contain an arbitrary interface in their data
field. The kind of interface that is contained in a notification must be
specified in the dataKind
field.
There are predefined kinds of objects for compile and test tasks, as described in [[bsp#BuildTargetCompile]] and [[bsp#BuildTargetTest]]
export type TaskFinishDataKind = string;
export namespace TaskFinishDataKind {
/** `data` field must contain a CompileReport object. */
export const CompileReport = "compile-report";
/** `data` field must contain a TestFinish object. */
export const TestFinish = "test-finish";
/** `data` field must contain a TestReport object. */
export const TestReport = "test-report";
}
TaskFinishData
export type TaskFinishData = any;
OnRunPrintStdout: notification
Unstable (may change in future versions)
Notification sent from the server to the client when the target being run or tested prints something to stdout.
- method:
run/printStdout
- params:
PrintParams
PrintParams
Unstable (may change in future versions)
export interface PrintParams {
/** The id of the request. */
originId: Identifier;
/** Relevant only for test tasks.
* Allows to tell the client from which task the output is coming from. */
task?: TaskId;
/** Message content can contain arbitrary bytes.
* They should be escaped as per [javascript encoding](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Grammar_and_types#using_special_characters_in_strings) */
message: string;
}
OnRunPrintStderr: notification
Unstable (may change in future versions)
Notification sent from the server to the client when the target being run or tested prints something to stderr.
- method:
run/printStderr
- params:
PrintParams
TaskFinishData kinds
CompileReport
This structure is embedded in
the data?: TaskFinishData
field, when
the dataKind
field contains "compile-report"
.
CompileReport
The completion of a compilation task should be signalled with a
build/taskFinish
notification. When the compilation unit is a build target,
the notification's dataKind
field must be compile-report
and the data
field must include a CompileReport
object:
export interface CompileReport {
/** The build target that was compiled. */
target: BuildTargetIdentifier;
/** An optional request id to know the origin of this report.
* Deprecated: Use the field in TaskFinishParams instead */
originId?: Identifier;
/** The total number of reported errors compiling this target. */
errors: Integer;
/** The total number of reported warnings compiling the target. */
warnings: Integer;
/** The total number of milliseconds it took to compile the target. */
time?: Long;
/** The compilation was a noOp compilation. */
noOp?: boolean;
}
TestFinish
This structure is embedded in
the data?: TaskFinishData
field, when
the dataKind
field contains "test-finish"
.
TestFinish
export interface TestFinish {
/** Name or description of the test. */
displayName: string;
/** Information about completion of the test, for example an error message. */
message?: string;
/** Completion status of the test. */
status: TestStatus;
/** Source location of the test, as LSP location. */
location?: Location;
/** Kind of data to expect in the `data` field. If this field is not set, the kind of data is not specified. */
dataKind?: TestFinishDataKind;
/** Optionally, structured metadata about the test completion.
* For example: stack traces, expected/actual values. */
data?: TestFinishData;
}
TestStatus
export enum TestStatus {
/** The test passed successfully. */
Passed = 1,
/** The test failed. */
Failed = 2,
/** The test was marked as ignored. */
Ignored = 3,
/** The test execution was cancelled. */
Cancelled = 4,
/** The was not included in execution. */
Skipped = 5,
}
TestFinishDataKind
export type TestFinishDataKind = string;
export namespace TestFinishDataKind {}
TestFinishData
export type TestFinishData = any;
TestReport
This structure is embedded in
the data?: TaskFinishData
field, when
the dataKind
field contains "test-report"
.
TestReport
export interface TestReport {
/** Deprecated: Use the field in TaskFinishParams instead */
originId?: Identifier;
/** The build target that was compiled. */
target: BuildTargetIdentifier;
/** The total number of successful tests. */
passed: Integer;
/** The total number of failed tests. */
failed: Integer;
/** The total number of ignored tests. */
ignored: Integer;
/** The total number of cancelled tests. */
cancelled: Integer;
/** The total number of skipped tests. */
skipped: Integer;
/** The total number of milliseconds tests take to run (e.g. doesn't include compile times). */
time?: Long;
}
TaskStartData kinds
CompileTask
This structure is embedded in
the data?: TaskStartData
field, when
the dataKind
field contains "compile-task"
.
CompileTask
The beginning of a compilation unit may be signalled to the client with a
build/taskStart
notification. When the compilation unit is a build target, the
notification's dataKind
field must be "compile-task" and the data
field must
include a CompileTask
object:
export interface CompileTask {
target: BuildTargetIdentifier;
}
TestStart
This structure is embedded in
the data?: TaskStartData
field, when
the dataKind
field contains "test-start"
.
TestStart
export interface TestStart {
/** Name or description of the test. */
displayName: string;
/** Source location of the test, as LSP location. */
location?: Location;
}
TestTask
This structure is embedded in
the data?: TaskStartData
field, when
the dataKind
field contains "test-task"
.
TestTask
The beginning of a testing unit may be signalled to the client with a
build/taskStart
notification. When the testing unit is a build target, the
notification's dataKind
field must be test-task
and the data
field must
include a TestTask
object.
export interface TestTask {
target: BuildTargetIdentifier;
}