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
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ Schema 只检查 JSON 结构。ID 引用、权限、激活事件、模板变量
| [Java](sdk/java/README.md) | Java 8+ | `sdk-java-v<版本>` | `lithe-plugin-sdk-java-<版本>.jar` 和 `.sha256` | shade 进后端 JAR |
| [Rust](sdk/rust/README.md) | Rust 1.87+ | `sdk-rust-v<版本>` | `lithe-plugin-sdk-rust-<版本>.crate` 和 `.sha256` | 用 Git 依赖锁定标签(`Cargo.lock` 记录 commit),或解压后作为 `path` 依赖;编译成每个平台各一份的插件后端可执行文件 |

SDK 的源码都在本仓库的 `sdk/` 下,发布在[本仓库的 Releases](https://github.com/Lithe-IDEA/lithe-plugin-docs/releases) 里,不在 npm、Maven 或 crates.io 上。Rust SDK 目前只实现插件后端(`backend`):插件函数和宿主服务(插件函数协议 1–3);构建后端请用 Node.js 或 Java SDK,VCS 后端请用 Node.js SDK。各 SDK 实现的协议版本见[宿主与官方 SDK 对照](reference/capabilities-and-versions.md#宿主与官方-sdk-对照)。Java SDK 0.1.0 是搬到这里之前从 Lithe 主仓库发布的,[那个 Release](https://github.com/1lck/Lithe-IDEA/releases/tag/sdk-java-v0.1.0) 继续可用,已经锁定它的插件不用改。
SDK 的源码都在本仓库的 `sdk/` 下,发布在[本仓库的 Releases](https://github.com/Lithe-IDEA/lithe-plugin-docs/releases) 里,不在 npm、Maven 或 crates.io 上。Rust SDK 目前只实现插件后端(`backend`):插件函数和宿主服务(插件函数协议 1–4);构建后端请用 Node.js 或 Java SDK,VCS 后端请用 Node.js SDK。各 SDK 实现的协议版本见[宿主与官方 SDK 对照](reference/capabilities-and-versions.md#宿主与官方-sdk-对照)。Java SDK 0.1.0 是搬到这里之前从 Lithe 主仓库发布的,[那个 Release](https://github.com/1lck/Lithe-IDEA/releases/tag/sdk-java-v0.1.0) 继续可用,已经锁定它的插件不用改。

规则只有一条:**在构建时下载,并按你锁定的 SHA-256(或 Git commit)校验;运行时不下载任何东西。** 插件包安装后没有 `npm install` 步骤,也必须能离线运行。

Expand Down Expand Up @@ -313,7 +313,7 @@ A plugin that uses only language servers, run, and test needs no backend. When y
| [Java](sdk/java/README.md) | Java 8+ | `sdk-java-v<version>` | `lithe-plugin-sdk-java-<version>.jar` and `.sha256` | Shade it into the backend JAR |
| [Rust](sdk/rust/README.md) | Rust 1.87+ | `sdk-rust-v<version>` | `lithe-plugin-sdk-rust-<version>.crate` and `.sha256` | Pin the tag as a Git dependency (`Cargo.lock` records the commit), or unpack it as a `path` dependency; compile one backend executable per platform |

All SDK sources live under `sdk/` in this repository and are published in [this repository's Releases](https://github.com/Lithe-IDEA/lithe-plugin-docs/releases), not on npm, Maven, or crates.io. The Rust SDK implements only the plugin backend (`backend`): plugin functions and host services (plugin function protocol 1–3); write build backends with the Node.js or Java SDK and VCS backends with the Node.js SDK. For the protocol versions each SDK implements, see [Host and official SDKs](reference/capabilities-and-versions.md#host-and-official-sdks). Java SDK 0.1.0 was released from the Lithe repository before the move; [that Release](https://github.com/1lck/Lithe-IDEA/releases/tag/sdk-java-v0.1.0) stays available, and plugins pinned to it need no change.
All SDK sources live under `sdk/` in this repository and are published in [this repository's Releases](https://github.com/Lithe-IDEA/lithe-plugin-docs/releases), not on npm, Maven, or crates.io. The Rust SDK implements only the plugin backend (`backend`): plugin functions and host services (plugin function protocol 1–4); write build backends with the Node.js or Java SDK and VCS backends with the Node.js SDK. For the protocol versions each SDK implements, see [Host and official SDKs](reference/capabilities-and-versions.md#host-and-official-sdks). Java SDK 0.1.0 was released from the Lithe repository before the move; [that Release](https://github.com/1lck/Lithe-IDEA/releases/tag/sdk-java-v0.1.0) stays available, and plugins pinned to it need no change.

There is one rule: **download at build time and verify against the SHA-256 (or Git commit) you pinned; download nothing at run time.** An installed package has no `npm install` step and must run offline.

Expand Down
68 changes: 64 additions & 4 deletions guides/plugin-backend-workspace.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
> 只提供 `backend: [1]` 的旧宿主会以 `plugin.api.unsupported` 拒绝 `backend` 2 的插件,所以老版本 Lithe
> 不会启动一个期待工作区上下文的进程。三个官方 SDK 都实现了协议 3:Node.js SDK 0.2.0、Java SDK 0.2.0 和 Rust SDK 0.1.0 起
> (见各自 README 的 Host services:[Node.js](../sdk/node/README.md#host-services)、[Java](../sdk/java/README.md#host-services)、
> [Rust](../sdk/rust/README.md#host-services))。宿主还支持函数协议 4(跨插件调用,见第 10 节),三个官方 SDK 目前只实现到协议 3。
> [Rust](../sdk/rust/README.md#host-services))。函数协议 4(跨插件调用,见第 10 节)由 Node.js SDK 0.4.0、Java SDK 0.4.0 和 Rust SDK 0.3.0 起实现。
> 用其他语言或更早的 SDK 需要自己处理下文的请求和通知。
> 各宿主支持到哪一版,见按最新 preview 核对的[版本对照](../reference/capabilities-and-versions.md)。

Expand Down Expand Up @@ -269,7 +269,37 @@
- 只协商到 3 的后端照常工作。它不能调用 `functions/*`;它导出的函数仍可被中转调用,但收不到 `caller`,要按调用方判断就必须协商 4。
- 导出或调用跨插件函数,清单要声明 `pluginFunctions`:`pluginAPIVersion` 不低于 3,`requires` 里写 `pluginFunctions: 1`、`backend: 2`、`serverProcess: 1`。
它不授予任何清单权限;清单声明了导出,后端仍要用 `lithe/function/register` 注册该函数。
- 目前只有 macOS 宿主实现;三个官方 SDK 还只协商到协议 3,没有 `functions/*` 的封装,也读不到 `caller`。
- 目前只有 macOS 宿主实现。

三个官方 SDK 都协商到协议 4,封装了 `functions/providers`、`functions/invoke`,被调函数能读到 `caller`;
协商到 3 及以下时,这两个方法在 SDK 本地以 `plugin.host.unavailable`(-32601)失败,不会发给宿主。
`parentOperationID` 不传时,SDK 取正在处理的 `lithe/function/invoke` 的 `operationID`。
下面以 Node.js 为例,[Java](../sdk/java/README.md) 和 [Rust](../sdk/rust/README.md) 的对应方法见各自 README:

```js
// Caller. The manifest declares pluginFunctions.calls for document.format.
backend.function('format.current', async (params, context) => {
const workspace = context.workspaceContext;
if (!workspace || !await context.host.supports('lithe/host/functions/invoke')) {
throw new PluginError('format.unavailable', 'Cross-plugin calls are unavailable.');
}
const { providers } = await context.host.functions.providers('document.format');
if (providers.length === 0) return null;
const { value } = await context.host.functions.invoke(workspace, {
pluginID: providers[0].pluginID,
functionID: 'document.format',
params: { path: params.path },
timeoutMilliseconds: 30000,
});
return value;
});

// Provider. `caller` is { pluginID } for a relayed call and null when the host started the call.
backend.function('document.format', async (params, context) => {
const callerID = context.caller?.pluginID ?? null;
return formatDocument(params, callerID);
});
```

### 11. 验证

Expand All @@ -293,7 +323,7 @@ The [contract](../contract/v1/README.md#backend-2-workspace-contexts) is normati
> An older host that offers only `backend: [1]` refuses a `backend` 2 plugin with `plugin.api.unsupported`, so an older Lithe
> never starts a process that expects workspace contexts. All three official SDKs implement protocol 3 from Node.js SDK 0.2.0, Java SDK 0.2.0, and Rust SDK 0.1.0
> (see Host services in each README: [Node.js](../sdk/node/README.md#host-services), [Java](../sdk/java/README.md#host-services),
> [Rust](../sdk/rust/README.md#host-services)). The host also supports function protocol 4 (cross-plugin calls, see section 10); the three official SDKs implement only up to protocol 3 so far.
> [Rust](../sdk/rust/README.md#host-services)). Function protocol 4 (cross-plugin calls, see section 10) is implemented from Node.js SDK 0.4.0, Java SDK 0.4.0, and Rust SDK 0.3.0.
> With another language or an earlier SDK, handle the requests and notifications below yourself.
> For how far each host supports each version, see the [version tables](../reference/capabilities-and-versions.md), which track the latest preview.

Expand Down Expand Up @@ -549,7 +579,37 @@ What to remember:
- A backend that negotiated only 3 keeps working as before. It cannot call `functions/*`; the functions it exports can still be called through the relay, but it never receives `caller`, so a provider that decides by who is asking must negotiate 4.
- To export or call cross-plugin functions, the manifest declares `pluginFunctions`: `pluginAPIVersion` 3 or later, with `pluginFunctions: 1`, `backend: 2`, and `serverProcess: 1` in `requires`.
It grants no manifest permission, and declaring an export does not register it: the backend still registers the function with `lithe/function/register`.
- Only the macOS host implements it so far; the three official SDKs still negotiate only up to protocol 3, have no wrapper for `functions/*`, and do not expose `caller`.
- Only the macOS host implements it so far.

All three official SDKs negotiate protocol 4, wrap `functions/providers` and `functions/invoke`, and expose `caller` to the called function;
when version 3 or lower is negotiated, both methods fail locally in the SDK with `plugin.host.unavailable` (-32601) and are never sent to the host.
When `parentOperationID` is omitted, the SDK uses the `operationID` of the `lithe/function/invoke` being handled.
The example below uses Node.js; for the matching methods in [Java](../sdk/java/README.md) and [Rust](../sdk/rust/README.md), see their READMEs:

```js
// Caller. The manifest declares pluginFunctions.calls for document.format.
backend.function('format.current', async (params, context) => {
const workspace = context.workspaceContext;
if (!workspace || !await context.host.supports('lithe/host/functions/invoke')) {
throw new PluginError('format.unavailable', 'Cross-plugin calls are unavailable.');
}
const { providers } = await context.host.functions.providers('document.format');
if (providers.length === 0) return null;
const { value } = await context.host.functions.invoke(workspace, {
pluginID: providers[0].pluginID,
functionID: 'document.format',
params: { path: params.path },
timeoutMilliseconds: 30000,
});
return value;
});

// Provider. `caller` is { pluginID } for a relayed call and null when the host started the call.
backend.function('document.format', async (params, context) => {
const callerID = context.caller?.pluginID ?? null;
return formatDocument(params, callerID);
});
```

### 11. Verification

Expand Down
Loading
Loading