Skip to content

feat(plugin): 插件自有语言服务器会话与后端决定启动方式(API-25,含 API-12/20/22) - #1745

Merged
xiaoyumuxi merged 26 commits into
previewfrom
feat/1495-plugin-language-server-api
Nov 5, 2026
Merged

xiaoyumuxi merged 26 commits into
previewfrom
feat/1495-plugin-language-server-api

Conversation

@xiaoyumuxi

@xiaoyumuxi xiaoyumuxi commented Nov 5, 2026 •

Copy link
Copy Markdown
Collaborator

Refs #1495

这个 PR 做了什么

让语言插件的后端拥有并驱动自己的语言服务器,并补齐通用通道,用来替代 Java 专属的启动、状态、虚拟文档和状态回收逻辑。这个 PR 只建基础设施:JDT 旧路径一条都不删,Windows 仍走旧路径。宿主和 Core 的新代码里没有 Java 词汇,也没有按插件名分支。

API-25:后端使用自己的语言服务器

  • 新增宿主方法 lithe/host/languageServer/request、notify、setStatus。清单权限 languageServer.request 授权这三个方法。

  • 会话策略由 Rust Core 执行,Swift 只做 I/O。具体规则如下:

    • 请求白名单。
    • 门控(gates)。
    • 串行命令:同类命令合并到同一个等待里。
    • 超时:默认 60000 ms,最长 300000 ms。
    • 排队上限:超过 128 个返回 busy。
    • 清单写了 remote:"unsupported" 时拒绝远程工作区。
  • 宿主向后端推送两个通知:didChangeState(starting/running/stopped/crashed)和 didReceiveNotification。两者都带 generation,上一代进程晚到的消息会被丢弃。

  • 新错误码,一码一义:

    • -32022 plugin.host.languageServerUnavailable
    • -32023 languageServerError
    • -32024 methodNotDeclared
    • -32026 foreignContribution

    超时、取消、busy、超限和前置条件失败沿用已有错误码。

  • 清单版本:languageServers 3 表示会话字段,serverProcess 3 表示 launch.kind:"backend"。pluginAPIVersion 仍为 4。

  • macOS 的 PluginManifest.hostCapabilities 宣告 languageServers [1, 2, 3] 和 serverProcess [1, 3]。Core 按精确版本比对,serverProcess 3 只允许由后端启动,和版本 2 的 runSelectedRuntime 没有重叠,所以 macOS 不需要一并宣告 2。

由后端决定服务器的启动方式

  • 分两步:
    1. Core 的 plugins.declarative.languageServerLaunchPlan 告诉宿主要调用哪个后端函数、超时多久、需要先创建哪些目录。
    2. 后端函数回答后,由 plugins.languageServers.decodeLaunch 在 Core 里校验,宿主再启动服务器。
  • 回答的可执行文件可以是插件包内文件,也可以是清单声明的工具。回答还可以带参数、环境变量、初始化选项、工作区配置、门控和 writablePaths。
  • 拒绝码为 plugin.launch.invalidResult、outsidePackage、undeclaredTool、unwritablePath、invalidRequest、unavailable 和 notBackend。
  • 工具类答案通过宿主工具链解析,工程内的工具会被拒绝。每次启动的临时目录在会话结束后回收。远程工作区暂时拒绝。服务器随插件包分发,运行时不往发行包写东西。
  • 只声明了“由后端启动”的语言服务器、没有其他触发器的 backend 2 插件也被视为合法。preview 新加的后端触发校验原本会拒绝这种插件,这里把它加入 provider_query_trigger,契约 README 的 “Backend 2: workspace contexts” 已同步。

API-12:内容提供者

  • 新增 lithe/host/documents/registerContentProvider,需要权限 documents.contentProvider。
  • 插件为某个 scheme 注册一个函数,宿主用 {context, uri} 调用它。返回值是字符串或 {content},上限 1 MiB,由 Core 解码。
  • 每个窗口每个 scheme 只能有一个提供者。

API-20:工作区状态与回收

  • 每个工作区的服务器状态放在 Application Support/Lithe/PluginState/<插件>/<语言>/workspaces/<哈希>/。
  • 回收哪些目录由 Core 根据清单的 state.retention 决定。Swift 只列出目录,并删除 Core 点名、且自己列出过的目录。
  • 以下内容不会被删:打开中的工作区、普通文件、符号链接。
  • 每次后端启动都会刷新目录时间,并在后台回收。回收失败不影响启动。
  • 目前没有用户可见的重置入口,只有引擎路径 rebuildWorkspaceState。

API-22:准备状态

  • setStatus 上报 preparing/ready/degraded/failed 状态、一段文字(不超过 1024 字节,按字符边界截断)和百分比。进程结束时状态随之清除。
  • 不复用 lithe/function/progress,因为它只属于一次正在运行的调用,而准备工作(导入构建、建索引)通常比任何一次调用都长。
  • 状态栏新增通用视图,只显示插件自己写的文字。兜底文案走 i18n,不含语言名。插件市场补了 languageServer.request 和 documents.contentProvider 的权限说明。

契约与文档

  • shared/contracts/plugins/v1/:
    • README 新增 “Backend-resolved launch” 和 “Plugin-owned sessions” 两节。
    • schema 已更新。
    • 新增两个 fixture,放在 docs(contracts): 插件契约 fixtures 按功能分目录并修正能力版本表 #1747 分好的 fixtures/languages/ 目录:language-server-backend-launch.plugin.json 和 language-server-launch-resolution.json。README 顶部的 fixture 表已登记这两个文件。
    • invalid-manifests.json 追加 19 个用例。
    • rust-core-api.md 追加 3 条命令。
  • 新增 Agent Note .agents/notes/implemented/architecture/2026-11-04-plugin-owned-language-server-sessions.md。
  • 功能矩阵新增 plugin-language-server-sessions:macOS 已实现、待验证,Windows 未实现。
  • docs/development/macos-plugin-api-plan.md 的 API-12、20、22、25 四行已更新。没有新增 API 编号。

其他小改动

  • 两处原有的尽力而为 try? 清理补了 log-exempt 理由。
  • 新增的 startPluginLanguageServer 重载只带会话策略,不带构建工具参数和 hostIntegrationLaunch。只有声明了会话字段、且没有 hostIntegration 的服务器走这个重载;其余服务器(包括带 hostIntegration 的官方集成)仍按 preview 原来的方式启动,不暴露给插件后端。无法执行会话策略的运行时,默认实现会把它当作普通插件后端启动,不带策略,因此插件后端无法访问该服务器。

JDT 旧路径与新通道的对应

旧路径在本 PR 中全部保留,macOS 的旧路径由后续 PR 删除,Windows 在 Windows 迁移 PR 中处理。

旧的 JDT 专属做法 新的通用通道
Java 虚拟文档 内容提供者(API-12)
is_java_build_command serializedCommands
java_configuration_running gates
project_preparation 状态条 setStatus(API-22)
引擎按名字 java 做的远程检查 清单 remote
MacJdtWorkspaceState / jdtCacheRetention state.retention + plugins.languageServers.stateRetention
hostIntegration: jdt launch.kind:"backend"

已知缺口

  • 远程工作区上由后端启动的服务器暂不支持。
  • setStatus 没有 actions,也没有 {done, total}。
  • 内容提供者上限 1 MiB,每次导航都会重新获取。
  • 转发的通知很多时,可能占满后端的 128 项队列。
  • 后端晚于服务器启动时,不会补发 running。
  • 关闭超时也会按 crashed 上报。
  • 取消串行队列的第一个请求,会连同合并进来的请求一起取消。
  • 宿主不发送 tools 参数。用户选了工程内的工具时,工具类启动会直接失败,不会回退到其他候选。
  • LSP 控制中心和工具设置里看不到后端启动的服务器用的是哪个可执行文件。
  • 没有用户可见的重置入口。回收只在后端启动时触发,失败时不提示。

合并顺序与后续事项

需要确认的问题

  1. 是否在本 PR 加“重置语言服务器状态”的用户入口?现在只有引擎路径。
  2. 宿主是否在本 PR 就发送 tools 参数?现在不发。
  3. 远程工作区上由后端启动的服务器什么时候支持?现在直接拒绝。
  4. setStatus 的 actions 和 {done, total} 是否要在 Java 插件接入之前补上?

entitlements 和 Info.plist 都没有改。

验证

合入 preview c5c6812 后的复验

上一轮 CI(e07197aaa)有两项失败:

之后以 merge 方式先合入 4bb1978,再合入 c5c6812,带进了 #1729(Windows 终端停靠宽度)、#1740(项目生成器工具字段,含 rustfmt 修正)、#1751(宿主方法按 API 编号登记)、#1752(删除工具链契约草案)和 #1730(编辑器 Provider 与编辑器动作第 2 版)。

冲突及处理:

  • 能力表在 README、schema、capabilities.rs 和 Swift hostCapabilities 里两边取并集:projectGenerators 用 preview 的 [1, 2],languageServers 和 serverProcess 保留本分支的版本 3。
  • verify-shared-contracts.sh:本分支的启动解析用例校验和 preview 的项目计划用例校验都保留,路径统一用 fixtures 变量。
  • invalid-manifests.json、declarative_plugins.rs 的 fixture 常量和校验列表:两边的用例都保留。
  • AppServices、MacServiceContainer、MacPluginBackendSessions、RustDeclarativePluginOperations:preview 的编辑器 Provider 服务和本分支的语言服务器宿主服务、内容提供者、后端启动准备都保留,各自注册到宿主分发器。
  • engine.rs 的 validate_start_request:同时校验本分支的 session_policy 和 preview 的 host_options。
  • docs/development/macos-plugin-api-plan.md 的 API-25 行:本分支已交付的语言服务器部分和 feat(plugins): 编辑器 Provider 与多车道编辑器动作(API-25、API-27) #1730 已交付的 Provider 部分合在一起;单元格里代码片段的 | 转义为 \|,避免表格断列。
  • AppModel+CodeNavigation.swift:本分支原有的内容提供者钩子(3 行)随 preview 的改动挪了位置。

已知的 preview 问题:scripts/architecture/verify-core.sh 的服务边界检查要求每个 AppModel 扩展不超过 600 行,而 preview 的 AppModel+CodeNavigation.swift 已有 627 行,合入后为 630 行,所以本地这一项不通过。CI 工作流不运行 verify-core.sh。拆分这个文件不在本 PR 范围内。

复验结果(macOS、Apple Silicon 本地):

  • scripts/rust-core/verify-rust-core-static.sh(与 CI 相同,cargo fmt --check 只查 lithe-core):通过。
  • cargo test -p lithe-core:共 1936 个测试,完整运行时 1926 个通过。另外 10 个失败:9 个是 remote::sessions::integration_tests,原因是两个工作树同时跑完整检查,本地 socket 报 EAGAIN(os error 35);1 个是 search_everywhere_pages_all_sources_past_200_without_duplicates_or_missing_matches。单独重跑这两组,19 个全部通过。
  • scripts/macos/test/test-macos.sh --filter,覆盖 PluginLanguageServerRelay、MacPluginLanguageServerWorkspaceState、PluginBackendLaunch、PluginContentProvider、PluginLanguageServerHostService、PluginLiveActivation、ProjectGeneration、ToolchainPluginAdmission、PluginManagementPresentation、PluginEditorProvider、PluginEditorAction:11 个套件 153 个测试全部通过。
  • 宿主语言特例闸门及其单测:每项计数与基线一致。
  • 以下检查全部通过:
    • verify-shared-contracts.sh、verify-module-boundaries.sh。
    • i18n 两项检查。
    • 功能矩阵及其变更检查。
    • Agent Note、日志用法与日志事件、Rust 注释规范、Java 语义基线、调试 v1 基线、git diff --check。
  • .agents/skills/write-stable-tests/scripts/verify-test-stability.sh --platform all --base c5c68126b --head HEAD:通过。

合入 preview ef6f853 后的复验

以 merge 方式合入 ef6f853,带进了 #1744(Core 生成文件 URI)、#1747(插件契约 fixtures 按功能分目录)、#1748(Git watcher)和 #1750(协议登记规则)。

冲突及处理:

  • README 顶部的 fixture 表采用 preview 的分目录表,在 fixtures/languages/ 一行补上本 PR 的两个 fixture。
  • README 能力表和 schema 的 languageServers 保留本分支的版本 3;serverProcess 行保留本分支的版本 3。
  • declarative_plugins.rs 的 fixture 常量采用 preview 的子目录路径,再补上本 PR 的 LANGUAGE_SERVER_BACKEND_FIXTURE。
  • 本 PR 的两个 fixture 用 git mv 移到 fixtures/languages/。Rust 测试、两个 Swift 测试、verify-shared-contracts.sh、rust-core-api.md 和功能矩阵里的引用都改到新路径;README 里的 fixtures/function-protocol.json 改为 fixtures/backend/function-protocol.json。
  • LSP-06: Unify document URI identities and diagnostic matching #1744 之后由 Core 生成文件 URI。本 PR 的启动请求原本就用 LspDocumentURI,两者没有语义冲突。

复验结果(macOS、Apple Silicon 本地):

  • cargo test -p lithe-core:1943 个通过,0 失败(单元测试 1909 个,集成测试 34 个)。
  • Swift 过滤测试(语言服务器宿主服务、后端启动、内容提供者、工作区状态、中转、同步桥、Rust 语言服务器启动):7 个套件共 66 个测试通过。另有 1 个测试跳过,它只在设置 LITHE_RUN_JAVA_DEBUG_INTEGRATION=1 时运行。
  • 宿主语言特例闸门:每项计数与基线一致,schemaEnums 为 13。
  • 以下检查全部通过:
    • scripts/architecture/verify-shared-contracts.sh、verify-core.sh、verify-module-boundaries.sh。
    • i18n 两项检查。
    • 功能矩阵(243 条)及其变更检查。
    • Agent Note、日志用法、Rust 注释规范、git diff --check。
  • preview 之后又合入了 fix(windows): 修复终端侧边停靠调整宽度后回跳 (#1703) #1729,只改 Windows 前端和一条 Agent Note,与本分支没有冲突,所以没有再合一次。

更早的验证

分支先 rebase 到 preview 的 c63bcd2,之后以 merge 方式合入 dbe8441(#1727)。合入时 docs/development/macos-plugin-api-plan.md 有冲突:本 PR 已交付的 API-12、20、22、25 行用本分支内容,其他 PR 的计划备注保留。

合入 #1727 后的复验(#1727 不改 Rust,合入时本 PR 的改动只涉及三个 Swift 文件和 manifest schema):

  • node scripts/architecture/verify-no-host-language-specifics.mjs 和它的单元测试:通过,每项计数与基线一致。
  • scripts/architecture/verify-core.sh、scripts/architecture/verify-module-boundaries.sh、node scripts/i18n/verify-app-language-localization.mjs、node scripts/i18n/generate-i18n.mjs --check、日志用法与日志事件、node --test scripts/plugins/plugin-settings-schema.test.mjs、git diff --check:全部通过。
  • Swift 过滤测试(语言服务器宿主服务、后端启动与启动解析、内容提供者、工作区状态、中转、宿主服务分发、后端会话、构建提供者会话、语言服务器状态、语言智能模块、插件管理展示等):15 个套件共 227 个测试全部通过。

合入 #1727 之前的验证(均在 macOS、Apple Silicon 本地完成):

  • cargo test -p lithe-core:1935 个通过,0 失败(单元测试 1902 个,集成测试 33 个)。
  • scripts/macos/test/test-macos.sh --filter ...:覆盖语言服务器宿主服务、后端启动与启动解析、内容提供者、工作区状态回收、宿主服务分发、后端会话、构建提供者会话、语言服务器状态、语言智能模块、声明式语言服务器等套件,共 276 个测试(18 个套件)全部通过。
  • 静态检查全部通过:
    • scripts/architecture/verify-shared-contracts.sh、Rust Core 注释规范、Agent Note、功能矩阵及其变更检查。
    • node scripts/i18n/verify-app-language-localization.mjs、node scripts/i18n/generate-i18n.mjs --check。
    • 日志用法与日志事件、Java 语义基线、调试 v1 基线。
    • 服务边界(含 scripts/macos/verify/verify-runtime-bundle-immutability.sh)、模块边界。
    • git diff --check,以及改动的 .rs 文件的 rustfmt。
  • lithe-plugin-docs 的 node scripts/sdk-e2e.mjs --source <本工作树> --ref feat/1495-plugin-language-server-api:构建、Java、Node、Rust 四组共 9 个测试全部通过。这一项是在 rebase 到最新 preview 之前的提交 3889fe692 上跑的;rebase 没有冲突,rebase 后重跑了 Core 测试、Swift 测试和静态检查。
  • 在 macOS 上运行 cargo check --bin lithe-windows:只有 preview 原有的两个 Windows 专属错误(project_window_registry.rs 的 os::windows 和 as_raw_handle),本 PR 没有新增。Windows 实际构建以 CI 为准。
  • 本次没有启动 Lithe 应用,没有做真机验证,所以功能矩阵标为“已实现、待验证”。

…thods (API-25)

Add languageServers 3 session fields, serverProcess 3 backend launch with
plugins.languageServers.decodeLaunch, and the languageServer host methods,
notifications, permissions and error codes -32022/-32023/-32024/-32026.
- add the session policy engine for plugin-owned language servers: declared
  method and command whitelist, serialized commands that join the running
  one, gates that hold requests until the server reports readiness, and a
  bound on waiting requests
- send backend requests and notifications to the plugin's own server
  through lsp.pluginServerRequest and lsp.pluginServerNotify; the server's
  result reaches the backend untouched and server errors keep their code
  and message as details
- end every operation in one place (the request-completed hook), so answer,
  cancel, timeout and session failure leave the policy consistent
- forward the notifications the plugin declared as pluginServerNotification
- refuse a session of another contribution, a stopped server and a remote
  workspace the plugin marked unsupported
- register plugins.languageServers.decodeLaunch and stateRetention
Document the backend-resolved language server launch (serverProcess 3) and
the session fields of languageServers 3 in the plugin contract: README,
manifest schema, a backend-launch fixture, golden launch-resolution cases,
and invalid-manifest cases. Add the languageServer host methods, content
provider, and host notifications to the README, and the four new Core
commands to rust-core-api.md.

Core tests run the golden cases, check the normalized session declaration,
the host capability refusal, and the install review program. The contract
verifier checks the new golden file.
宿主侧读取 launch.kind=backend 的声明、两步启动计划(先向后端询问命令行,
再让 Core 解码答案)、state.retention 和 temporaryDirectory,并让安装审查
列出由后端决定命令行的语言服务器。不改变既有三种启动方式。
宿主会话把后端对自己语言服务器的请求和通知转给 Core(lsp.pluginServerRequest / lsp.pluginServerNotify),
把 sessionPolicy 随 lsp.startServer 交给 Core,并把 Core 转发的服务器通知和错误 details 原样带回后端。
策略校验、白名单、串行和超时全部在 Core,Swift 只做 I/O。
Route lithe/host/languageServer/request, notify and setStatus from a plugin
backend to the window's language server session, and deliver the server's
state changes and forwarded notifications back to the owning backend with a
per-process generation, so a replaced process never reaches the backend.
Add plugins.contentProviders.decode: a content provider function answers a string or {content}, and Core bounds it to 1 MiB so the host opens the text without interpreting it.
Register lithe/host/documents/registerContentProvider per workspace window, route navigation to a plugin scheme through the provider function, and open the answer as a read-only virtual document.
…end (API-25)

A language server declared with a backend launch (serverProcess 3) now starts
by asking the plugin's backend what to run. Rust Core builds the question and
bounds the answer; the host moves them between the backend, the file system
and the tool resolver.

- MacPluginLanguageServerLaunchResolver: backendLaunchQuestion and
  backendLaunchProcess wrap the two Core steps, create the host directories,
  and keep a per-start scratch directory in the temporary area.
- MacPluginBackendLaunchPreparer: calls the backend function in the window's
  workspace context, resolves a tool answer as the plugin's toolchain and
  refuses a program inside the project, drops a start whose context changed,
  and removes the scratch directory when the process ends or the start fails.
- The language server runtime enters the existing prepareProcess flow for a
  backend-resolved server; registration accepts a server without executable
  names; remote roots are refused with a message.
- PluginWorkspaceContexts.localContext(forFolder:) finds the context of the
  window that shows a folder.
- Two interface texts in shared/i18n.
…estion (API-25)

The README no longer promises a tools parameter the macOS host does not send
yet, and lists the host limits of backend launches today: remote workspaces,
project-local tool selection, and the per-start scratch directory.
…issions (API-22, API-25)

A plugin-owned language server can report preparing, ready, degraded or
failed through lithe/host/languageServer/setStatus. The workbench status
bar now shows the plugin's own text (or a neutral sentence when it sent
none) for the first server that is not ready, with the percentage when
given. The host adds no wording about any language or tool.

The plugin permission list explains the two new grants in plain words:
languageServer.request and documents.contentProvider.
…-25)

The host-service tests check what the host adds to request, notify and
setStatus: parameter ranges, option refusal, failure code mapping, no
sessions and a missing grant. The relay tests check generations, state
order, dropped notifications of a replaced process, status ownership,
the 1024-byte message cut and status cleanup.
…API-20)

The per-workspace state a plugin-owned server writes under
PluginState/<plugin>/<language>/workspaces/ had no bound. Rust Core already
decides which of those directories expire from the plugin's declared
state.retention; the host now lists them, hands Core the facts and removes
the names Core returns.

- MacPluginLanguageServerWorkspaceState: markUsed refreshes the directory
  time on each backend-launched start, prune deletes what Core names (never
  an open workspace, never a file or link, never a name it did not list), and
  reset discards one workspace's state.
- The preparer runs the sweep in the background after the launch question is
  built; a failure is not reported to the start.
- The workspace state resetter closure handles plugin servers that have no
  host integration, so rebuildWorkspaceState reaches them.
- DeclarativeLanguageServerLaunchSource carries stateRetention.
- Mark two best-effort scratch cleanups with log-exempt reasons.
…nguage server (API-20)

The retention entries are the host's per-workspace directories, not the
sub-directories a plugin makes inside its own workspaceStateDirectory. The
host refreshes their time on each start and sweeps in the background. Discard
of one workspace's state exists in the engine only; the claim of a generic
user action is removed.
…PI-12, API-20, API-22)

macOS implements the host methods, backend launch, content providers, state
pruning and status display; Windows has no plugin backend host and keeps the
legacy path, so it stays missing.
Why the host methods, session policy, generations, setStatus, backend launch
and state retention live where they do, what the JDT paths map to, and what
was rejected.
…erver sessions

API-12 gains the read-only content provider, API-20 the language server's
per-workspace state retention, API-22 the server preparation status and API-25
the languageServers 3 / serverProcess 3 session and backend launch. All are
macOS-only; the rows keep what is still missing.
…ckend

Backend 2 validation, added on preview, rejects a backend without a page, command, workspace or provider trigger. A language server with launch.kind backend asks the backend for its command line, so it is such a provider trigger.
…n capabilities

The new host services use L10n from LitheModuleAPI, and the state
retention call names RustCoreBridge.CoreCallError. macOS now announces
languageServers 3 and serverProcess 3 so plugins with backend-resolved
launches and plugin-owned sessions pass Core's exact version check.
@lithe-code-review

Copy link
Copy Markdown

Lithe Review

⏳ 正在以标准模式审查代码,完成或失败后会更新本评论。

@lithe-code-review

Copy link
Copy Markdown

Lithe 运行验收

版本:23252e6027cb02ab251bbe9ce6f9d7c9c4729e1f;状态:partial。
本报告独立于代码审查;只报告实际执行的场景,不代表所有问题均已修复。

对照:共同祖先 c63bcd2438ea10a1ff822251c5b08558046209ba → PR head;当前目标分支合并适用性:未运行。

  • 条件不足,未验证:Backend-resolved launch, exact capability negotiation, backend-only activation, safe launch-answer decoding, and preservation of existing declarative launches.
    • The inventory supplies Cargo and rustc but no Windows C/C++ compiler, native linker/SDK, or prebuilt Core artifact. rust/Cargo.lock includes ring and Tree-sitter dependencies built through cc. These prerequisites cannot be assumed or installed automatically.
  • 条件不足,未验证:API-25 host request/notify authorization, ownership, policy enforcement, error mapping, lifecycle notifications, generation isolation and bounded process ownership.
    • The new native host integration is macOS-only; Windows explicitly retains its old path. This environment has neither macOS/Swift nor a supplied fixture-confined native acceptance driver and executable backend/LSP fixture. Frontend mocks cannot substitute for this integration.
  • 条件不足,未验证:API-12 content-provider lifecycle and read-only navigation, API-22 preparation status, and API-20 native workspace-state retention and resource cleanup.
    • Requires a macOS interactive desktop and a preprovisioned acceptance build with storage confined to the fixture. Neither is available. No genuine status-bar, navigation or read-only editor workflow can run headlessly on Windows. A native filesystem driver is also needed to inspect retention and cleanup without using the user's Application Support directory.

未覆盖:

  • All three planned scenarios remain unexecuted; there is currently no runtime acceptance evidence for their requirements.
  • Core launch acceptance/rejection, exact capability negotiation, manifest permissions and backend-only activation need an available native build toolchain or revision-matched Core artifacts.
  • Actual backend invocation, packaged/tool executable resolution, rejection of project-local tools, workspace-context changes during launch, remote rejection and native process cleanup remain unverified.
  • Request/notify policy enforcement, gates, command coalescing, default 60000 ms and maximum 300000 ms timeouts, cancellation, the 128-waiter limit, payload limits and error mappings remain unverified.
  • Lifecycle generation isolation, notification forwarding, status ownership/clearing, late backend startup without running replay, shutdown-timeout crash reporting and cancellation of coalesced callers remain unverified.
  • Content-provider permissions, scheme validation, per-window uniqueness, teardown, decoding limits, repeated fetches and genuine read-only navigation remain unverified.
  • Native state-directory placement, age/count retention, active-directory preservation, timestamp refresh, best-effort cleanup failure and engine-only rebuildWorkspaceState remain unverified. Symlink preservation additionally requires a supplied permissible fixture; the probe must not create links.
  • Status-bar presentation, localized fallback text and marketplace permission descriptions require macOS desktop acceptance.
  • Runtime package immutability, temporary-directory cleanup and existing JDT-path regression coverage remain unverified. Java is unavailable, and Windows native application behavior is outside the supplied headless capability.
  • The full schema/invalid-manifest corpus, public documentation synchronization and SDK end-to-end compatibility are outside these three runtime scenarios; no external repository synchronization or SDK validation was performed.
  • Performance and intermittent reliability are not covered; acceptance would require a prespecified statistical protocol.

工作副本与运行状态已清理;可复用编译缓存按 12 GiB / 7 天预算保留。
详细步骤和原始证据保存在服务器受限目录(14 天、总计不超过 1 GiB);当前没有公开下载链接。

- Plan doc: keep this PR's delivered API-12/20/22/25 rows and the other
  PRs' plan notes; take preview's rows elsewhere.
- The new startPluginLanguageServer overload carries the session policy
  and no build-tool or host-integration parameters. A server with a
  session policy and no hostIntegration starts through it; any other
  server keeps preview's start unchanged.
- The manifest schema forbids hostIntegration on a backend-resolved
  launch with not/required instead of a false property schema; the
  meaning is the same.
@lithe-code-review

Copy link
Copy Markdown

Lithe 运行验收

版本:a97572514f96e77e460cf7c1a70c34d025ff2318;状态:partial。
本报告独立于代码审查;只报告实际执行的场景,不代表所有问题均已修复。

对照:共同祖先 dbe8441e27486fef26f0e915e8c6a862c307e180 → PR head;当前目标分支合并适用性:未运行。

  • 条件不足,未验证:Backend-only activation, exact capability negotiation, backend-resolved launch validation, and preservation of existing declarative launches.
    • Core requires native compilation: rust/Cargo.lock includes ring and Tree-sitter dependencies using cc. The supplied inventory contains no Windows C compiler, native linker/SDK, or revision-matched Core artifact and driver. Cargo and rustc alone do not establish these prerequisites.
  • 条件不足,未验证:API-25 request/notify permissions, ownership, request policy, gates, serialization, error propagation and generation isolation.
    • The production host integration is macOS-only; Windows retains the old path. This environment provides neither macOS/Swift nor a revision-compatible foreground native acceptance driver with fixture-confined storage and real executable backend/LSP fixtures.
  • 条件不足,未验证:API-12 provider lifecycle, API-22 status lifecycle, and API-20 native workspace-state retention and resource cleanup.
    • These production services and filesystem adapters are implemented in Swift for macOS. A macOS native driver using real Core, fixture-rooted application storage, deterministic timestamps and observable lifecycle completion is unavailable. Existing scripted host tests cannot establish this combined runtime workflow.

未覆盖:

  • All selected scenarios remain unexecuted; there is no new runtime acceptance evidence for any requirement.
  • Manifest compatibility remains unverified: pluginAPIVersion 4, exact languageServers/serverProcess versions, macOS advertising serverProcess [1,3], permission consistency, backend-only activation and legacy declarative-launch compatibility.
  • Launch planning and decoding remain unverified: resolver arguments, settings, four required directories, default/configured resolver timeout, packaged versus declared-tool answers, environment, initialization options, workspace configuration, gates, writable paths, unknown fields and every size/path bound.
  • All seven launch rejection codes remain unverified: invalidResult, outsidePackage, undeclaredTool, unwritablePath, invalidRequest, unavailable and notBackend.
  • Actual backend invocation, executable validation, tool discovery, project-local tool rejection without fallback, workspace-generation changes during resolution, backend failure/cancellation and remote-workspace rejection remain unverified. The documented omission of tools from host arguments is also unverified.
  • API-25 permissions, ownership, method/command allowlists, reserved methods, notification rules and workspace/configuration updates remain unverified.
  • Request gates, FIFO release, serialized-command coalescing, leader cancellation, the 128-waiter boundary, default 60000 ms timeout, maximum 300000 ms timeout, cancellation propagation and payload/result bounds remain unverified.
  • Error mappings remain unverified, including -32022 unavailable, -32023 server error, -32024 undeclared method, -32026 foreign contribution, existing timeout/cancelled/busy/limit/precondition codes, and removal of upstream error data.
  • Lifecycle notifications, generation isolation, notification truncation, pending-request completion after stop/crash/restart/disable, late-backend startup without running replay, shutdown-timeout crash reporting and backend-queue saturation remain unverified.
  • API-12 permission checks, scheme grammar/reserved schemes, registered-function requirement, per-window uniqueness, all disposal paths, exact string/content-object decoding, the 1 MiB UTF-8 boundary and 30-second failure path remain unverified.
  • Genuine virtual-document navigation, target position/history, read-only editing, refetch on reopening and visible failure handling require an interactive macOS desktop. No desktop workflow is runnable here.
  • API-22 status ownership, preparing/ready/degraded/failed states, percentage validation, replacement, 1024-byte character-boundary truncation and stop/restart clearing remain unverified. Status-bar presentation, ready-state hiding, tooltips, localized fallbacks and marketplace permission descriptions require macOS desktop acceptance.
  • API-20 storage placement, workspace hashing, age/count retention, deterministic ordering, active-directory preservation, no-retention behavior, unrelated-state isolation, timestamp refresh, background completion, best-effort failure and engine-only rebuildWorkspaceState remain unverified. Symlink preservation additionally lacks a permissible supplied fixture under the prohibition on creating links.
  • Scratch cleanup after successful, failed and cancelled starts, persistent state across disable/update, process-tree cleanup, and application/plugin package immutability remain unverified.
  • Existing JDT workflows and mavenContext/javaGradle parameter forwarding remain unverified; Java is unavailable. Windows retaining its existing native path also lacks regression evidence.
  • The full schema and invalid-manifest corpus, SDK compatibility, public contract synchronization, documentation/matrix consistency, localization checks and architectural checks were not executed. Optional reset UI, status actions/done-total and remote backend-launch support remain documented scope decisions, not assumed implemented features.
  • Performance, memory use, notification-flood reliability and intermittent races are uncovered; acceptance requires a prespecified statistical protocol rather than a single successful run.

工作副本与运行状态已清理;可复用编译缓存按 12 GiB / 7 天预算保留。
详细步骤和原始证据保存在服务器受限目录(14 天、总计不超过 1 GiB);当前没有公开下载链接。

…anguage-server-api

# Conflicts:
#	rust/lithe-core/src/tests/declarative_plugins.rs
#	shared/contracts/plugins/v1/README.md
#	shared/contracts/plugins/v1/plugin-manifest.schema.json
…anguage-server-api

# Conflicts:
#	macos/Sources/LitheModuleAPI/Plugins/PluginTypes.swift
#	rust/lithe-core/src/plugins/capabilities.rs
#	rust/lithe-core/src/tests/declarative_plugins.rs
#	scripts/architecture/verify-shared-contracts.sh
#	shared/contracts/plugins/v1/fixtures/manifest/invalid-manifests.json
#	shared/contracts/plugins/v1/plugin-manifest.schema.json
# Conflicts:
#	docs/development/macos-plugin-api-plan.md
#	macos/Sources/Lithe/Application/Composition/AppServices.swift
#	macos/Sources/Lithe/Core/Rust/RustDeclarativePluginOperations.swift
#	macos/Sources/Lithe/Platform/MacOS/MacServiceContainer.swift
#	macos/Sources/Lithe/Platform/MacOS/Plugins/MacPluginBackendSessions.swift
#	rust/lithe-core/src/lsp/interface/engine.rs
#	rust/lithe-core/src/tests/declarative_plugins.rs
#	shared/contracts/plugins/v1/fixtures/manifest/invalid-manifests.json
合入 #1742(插件函数中转)。冲突全部是两边在同一位置各自新增:
HostParams 与校验函数、错误码表(-32022..-32026 与 -32027..-32071 不重叠)、
SessionState 字段、request 事件分发、契约 README 与 fixture。
provider_query_trigger 合成为 toolchain、keymap、后端启动语言服务器、
导出函数四个条件之一即可。
@xiaoyumuxi
xiaoyumuxi merged commit cd79e71 into preview Nov 5, 2026
8 of 10 checks passed
xiaoyumuxi added a commit that referenced this pull request Nov 5, 2026
preview 合入了 #1745(插件自有语言服务器会话与后端决定启动方式)。冲突处理:

- serverProcess 版本改为累积语义:选中运行时的调试适配器需要 2,后端
  决定启动方式的语言服务器需要 3,requiresTools 需要 4;4 覆盖 2 和 3,
  清单仍须声明覆盖所用特性的最低版本。capabilities 列表为 [1, 2, 3, 4],
  schema、契约 README 同步说明。macOS 宣告的版本保持 preview 的 [1, 3]。
- 主机通知沿用本分支的 grant 字段与 admitted(),admitted() 改用 #1745
  的 holds_service,按方法授予的服务也能收到对应通知;run/didExit 与两个
  languageServer 通知并存。
- 权限、错误码(-32022..-32026 按序)、通知参数校验、README 章节、契约
  fixture、MacServiceContainer 的宿主服务注册、计划文档 API-22 行均取并集。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

review: high ghfind author score; see https://ghfind.com

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant