Skip to content

docs(contracts): 插件契约 fixtures 按功能分目录并修正能力版本表 - #1747

Merged
xiaoyumuxi merged 9 commits into
previewfrom
docs/plugin-contract-fixtures-by-domain
Nov 5, 2026
Merged

xiaoyumuxi merged 9 commits into
previewfrom
docs/plugin-contract-fixtures-by-domain

Conversation

@xiaoyumuxi

@xiaoyumuxi xiaoyumuxi commented Nov 5, 2026 •

Copy link
Copy Markdown
Collaborator

背景

shared/contracts/plugins/v1/fixtures/ 原来有 70 多个平铺文件,proposals/toolchains/ 又单独放了一套示例,插件开发者在 lithe-plugin-docs 的 contract/v1/ 里找不到某个功能对应的清单和用例。契约 README 的能力版本表也有遗漏和重复。本 PR 只调整目录和路径、修正版本表,不改任何契约语义;fixture 内容除路径引用外逐字节不变。

改动

1. fixtures 按功能分目录

子目录 内容
manifest/ hello-lithe.plugin.json、invalid-manifests.json(跨领域的清单拒绝用例)
languages/(含 grammars/) 语言、语法、打包/系统命令语言服务器、Node 运行时、command-plans.json、runtime-versions.json
backend/ 后端、命令后端、终端后端、后端工作区、function-protocol.json、plugin-logging.json
editor/ editor-actions.plugin.json
ui/ 原生控件/表单/面板、网页面板
settings/ settings-v2.plugin.json
build-systems/ 声明式构建(buildSystems)清单与 build-plans.json
build-providers/ 构建提供者(buildProviders)清单与执行/测试/配置/调试准备协议用例
debug-adapters/ 调试适配器清单与拒绝用例
vcs/ vcs-provider.plugin.json
keymap-import/ keymap-import-provider.plugin.json
project-generators/(含 templates/) 项目生成器清单、project-plans.json,模板从 project-generator-templates/ 移入 templates/
toolchains/(含 proposal/) 工具定义、工具链提供者清单;原 proposals/toolchains/fixtures/ 移入 proposal/
package-trust/ 发布者签名向量、随包发布者清单
marketplace/ 市场索引用例(原已是子目录,未改动)
  • 项目生成器模板里的 Java 示例(dev.lithe.fixture.java-support、main/Main.java、java-tool-definition.json)按要求原样保留,只移动位置并修正引用路径。
  • 用例文件只按文件名引用基础清单,所以各子目录之间文件名必须唯一。

2. toolchains 文档合并

  • toolchains.md → toolchains/README.md
  • proposals/toolchains/(README、manifest.md、protocol.md、4 个 schema)→ toolchains/proposal/
  • 文档内的相对链接全部随之更新。

3. 顶层 schema 不动

plugin-manifest.schema.json、plugin-index.schema.json、native-ui.schema.json 的路径和 $id 都没变,已发布插件里写的 $schema URL 继续有效。

4. 契约 README 与 schema 的版本表修正

  • serverProcess:补版本 2(新增 runSelectedRuntime,供调试适配器使用,属于 API 级别 4),并注明 v2 目前只有 Rust Core 支持,macOS 和 Windows 宿主都只声明 1。
  • 构建提供者协议协商:宿主发送的 litheBuild 版本列表从 [8..1] 改为 Core 实际提供的 [11, 10, …, 1],并补上版本 9(不透明语义测试选择器)、10(类型化运行选项与服务/任务运行准备)、11(注册表连接调试)的说明,与 build_provider.rs 一致。
  • executableResolution:原来有两行重复,现合并为一行(v1 候选排序与严格选择;v2 增加工具定义候选,以及项目/子项目工具链注册表绑定)。
  • 补上缺失的 keymapImportProviders 行(1,仅 macOS;Windows 尚未声明)。
  • pluginAPIVersion 说明补上级别 4。
  • plugin-manifest.schema.json 中 requires.buildSystems 的枚举补 4,描述写明 v2/v3/v4 各自新增的内容(与 capabilities.rs 的 SUPPORTED_CAPABILITIES 一致);executionProviders 行修正缩进。

5. 校验脚本新增检查(scripts/architecture/verify-shared-contracts.sh)

  • fixtures/ 根目录不得有散落文件,新 fixture 必须放进某个功能子目录。
  • fixture 文件名在所有子目录间必须唯一。
  • 原有校验的路径全部改到新目录。

6. 引用方同步

  • Rust Core 测试(rust/lithe-core)里的 fixture 路径。
  • macOS 测试(macos/Tests/LitheTests 下 38 个测试文件)的 fixture 路径。
  • Windows:plugin_host/tests.rs 的 fixture_path 改为在 fixtures 下按文件名递归查找,web.rs 和 declarative-plugin-ui.test.ts 改为新路径。
  • macos/Experiments/Monaco/workbench.integration.ts 的语法路径。
  • .agents/notes、shared/contracts/rust-core-api.md、shared/contracts/vcs-provider-v1.md 中的路径链接。
  • shared/platform-feature-matrix/features/*.json 中 25 个功能文件的证据路径。
  • scripts/architecture/language-specifics-baseline.json 中键名改为新路径(计数不变)。

验证

  • zsh scripts/architecture/verify-shared-contracts.sh:通过
  • cargo test -p lithe-core:通过(1850 + 25 + 5 + 2 + 1,0 失败)
  • node --test 'scripts/architecture/*.test.mjs':17/17 通过
  • 宿主语言特定内容闸门本地 ratchet:与基线一致
  • node scripts/i18n/verify-app-language-localization.mjs、node scripts/i18n/generate-i18n.mjs --check:通过
  • 平台功能矩阵校验:通过(240 项)
  • 全仓库扫描旧的 fixtures/<文件名> 引用:无残留
  • Windows:macOS 上无法编译 lithe-windows(project_window_registry.rs 使用 std::os::windows,与本 PR 无关),改用静态检查确认 tests.rs 用到的每个 fixture 名在子目录中恰好命中一次,web.rs 的相对路径存在;需要 Windows CI 跑实际测试。
  • macOS Swift 测试(scripts/macos/test/test-macos.sh --filter,覆盖改了 fixture 路径的 38 个测试类):
    • 首轮 38 个类一起跑(476 个测试):4 个套件出现等待超时(DeadlineExceeded("session shutdown")、waitUntilOpen),没有任何 fixture 读取失败;
    • 只重跑这 4 个套件(102 个测试):剩 1 个超时;
    • 单独跑剩下的 WorkbenchContributionHostTests:32/32 通过;
    • 失败测试引用的 fixture 路径都已逐一确认存在。超时数量随并发负载变化,与本 PR 的路径改动无关。

合并说明

- fixtures/ 下的平铺文件按契约领域移入 manifest、languages、backend、editor、ui、
  settings、build-systems、build-providers、debug-adapters、vcs、keymap-import、
  project-generators、toolchains、package-trust、marketplace 子目录
- toolchains.md 移为 toolchains/README.md,proposals/toolchains/ 并入
  toolchains/proposal/(示例与用例在 fixtures/toolchains/proposal/)
- 项目生成器模板移入 fixtures/project-generators/templates/,Java 示例原样保留
- 三个顶层 schema 路径与 $id 不变
- verify-shared-contracts.sh 新增检查:fixtures/ 根目录不得有散落文件、
  fixture 文件名在各子目录间唯一(用例文件只按文件名引用基础清单)
- Rust Core、macOS、Windows 测试与 Agent Note、功能矩阵证据路径同步更新;
  Windows plugin_host 测试改为按文件名在子目录中查找 fixture
- 契约 README 能力版本表:serverProcess 补版本 2,合并重复的
  executableResolution 行,补 keymapImportProviders 行,API 级别补 4;
  schema 的 requires.buildSystems 枚举补 4
macOS 的 PluginManifest.hostCapabilities 与 Windows 的 host_capabilities() 都只声明 serverProcess 1,需要 serverProcess 2(debugAdapters 的 runSelectedRuntime)的插件目前在两个平台都会被宿主拒绝。
构建提供者一节写的宿主提供版本还停在 [8…1],与同文件前文和 Core build_provider.rs 的 SUPPORTED_VERSIONS(11…1)不一致;补上 9(语义测试选择器)、10(类型化运行选项与服务/任务运行准备)、11(注册表连接调试)的说明。
@ghfind-review ghfind-review Bot added the review: high ghfind author score; see https://ghfind.com label Nov 5, 2026
- 契约目录表和工具链 fixtures 说明:macOS 已为设置页、Build 与运行工具使用插件工具链,Windows 未接入
- 工具链一节:Build 工具和运行计划里指向插件定义工具的 toolchain 可执行文件走独立的新鲜解析
- 能力表 toolDefinitions/toolchainProviders/executableResolution 的宿主说明同步
- Shared executable candidates 锚点改为 -12(两处)
- 快捷键导入:macOS 已声明能力,三个官方 SDK 已实现
- Current Windows availability:Windows 声明 ui 1、2,不声明 3、4
- 工具链提案 README 的示例目录改为 fixtures/toolchains/proposal/
- vcs-provider-v1 状态行:macOS 已启动提供者
- toolchains/README.md 状态段原说 Windows 已有目录固定、声明式扫描、shell 候选和提供者查询的 Build 管道;这些代码在未合入的 Draft #1722,preview 的 Windows 宿主没有工具链适配器,也不声明 toolDefinitions、toolchainProviders。改为如实说明,并写明 Core 在 Windows 上拒绝需要这两项能力的包。
Core 的 plugins.marketplace.validateIndex 只在 darwin-* 平台把没有 requires 的级别 2 版本标为可用,Windows 只支持从磁盘安装声明式插件、没有市场浏览入口。Lua 模板第 5 步原写可列 macOS 和 Windows,改为只列 darwin-*;顶部工具链说明不再写死命令数量。
Windows #1424 已实现私有快照、installReview 和用户确认的磁盘安装,原文仍写 Windows 没有这套流程。改为写明它做了什么,以及与 macOS 的差距:不验证发布者签名、只比对 plugin.json、不记录已批准程序和来源、没有市场安装入口。
Windows 的签名验证还在未合入的 Draft #1478,preview 上只有 macOS 的 PluginPackageSignature 测试使用这组向量。
@xiaoyumuxi
xiaoyumuxi marked this pull request as ready for review November 5, 2026 03:29
@xiaoyumuxi
xiaoyumuxi merged commit 644afda into preview Nov 5, 2026
2 of 3 checks passed
xiaoyumuxi added a commit that referenced this pull request Nov 5, 2026
* feat(core): 插件函数中转的协议第 4 版与 pluginFunctions 清单校验

- 清单新增 requires.pluginFunctions:导出项 {id, version, context},调用声明 {id, version},context 第一阶段只有 workspace
- litheFunctions 协商版本新增 4,开放 lithe/host/functions/providers 与 lithe/host/functions/invoke
- 被调方收到由 Core 写入的 caller.pluginID(仅协议 4 以上)
- 新增 9 个 plugin.function.* 拒绝原因及对应数值错误码
- 旧的 wrongPlugin / recursiveCall 检查保持不变

* feat(core): relay plugin function calls between plugin backends

Add the cross-plugin function relay state machine (function_relay.rs) and
wire it into the LSP interface engine. A backend that negotiated
litheFunctions 4 can discover providers and invoke an exported function
through Core. Core checks declaration, export, enablement, version,
context, call chain, depth, per-caller concurrency and byte limits, and
propagates cancellation down the chain.

Refs #1495

* test(core): cover the cross-plugin function relay on real sessions

Scripted Python, Go and Rust plugin backends exercise the relay through the
engine: the call path with the Core-written caller field, discovery, every
refusal, cycles, cancellation down the chain, timeouts, loss of a caller or
callee, hot disabling, waiting for a provider the host starts, and provider
selection by workspace. The old recursiveCall and wrongPlugin refusals are
asserted unchanged.

* docs(contract): 插件函数跨插件调用的清单 schema、夹具与 README

- schema 新增 requires.pluginFunctions 与 pluginFunctions(exports 为 {id, version, context},calls 为 {id, version})
- 新增导出方、调用方两个有效夹具,以及 12 个无效清单用例
- README 新增“跨插件调用(协议第 4 版)”:私有与导出、发现与调用方法、调用链、caller 字段、错误码
- verify-shared-contracts.sh 校验 invocationCallers 与 relayErrors,并要求新错误码一码一号
- Core 夹具测试覆盖导出排序与 functions 宿主服务授权

* feat(macos): 接入插件函数中转的快照发布与被调方后端启动

Core 负责中转的全部判断,macOS 只做 I/O:

- MacPluginBackendSessions 在注册、工作区上下文变化、启用、禁用和包变更后,
  把清单里的 pluginFunctions 原样和上下文事实一起交给 Core
  (lsp.configureFunctionRelay),快照没变就不重复发布。
- 收到 functionProviderStartRequired 时,用普通的插件启动流程启动被调方后端,
  失败走既有的激活失败回报,等待上限由 Core 的 30 秒和会话初始化超时共同限定。
- PluginHostServiceDispatch 把 functions 服务列为 Core 直接应答的授权,
  不再被 supportedGrants 丢弃。
- hostCapabilities 增加 pluginFunctions,旧宿主仍会拒绝声明它的插件。
- 增加快照发布、被调方启动和 functions 授权的单测。

* docs(contract): 记录 lsp.configureFunctionRelay 命令

补充 Rust Core API 文档中的命令表和说明:载荷是插件的 exports/calls 与
工作区上下文快照,返回空对象,并链接到契约 README 的跨插件调用一节。

* docs(notes): 记录插件函数跨插件中转的第一阶段,并登记功能矩阵

- 已实现 Note(插件函数契约)新增决策 8:清单导出与调用声明、协议 4 的两个
  宿主请求、Core 检查顺序、调用链与取消、信任不传递与 caller 字段、被调方
  未运行时的启动请求、热激活、远程工作区,以及被否的方案和后果。
- 提议 Note(插件依赖与导出)只更新已落地的第一阶段,并写明依赖解析、版本
  冲突、依赖闭包、资源租约仍未实现,整篇 Note 仍留在提议中。
- 功能矩阵新增 plugin-cross-plugin-function-calls:macOS 部分实现、待原生
  验收,Windows 无插件后端宿主、行为不变;plugin-functions 指向新条目。

* fix(core): 中转调用的被调方失败使用独立数值错误码

被调函数返回错误(plugin.function.failed)和没有可用结果
(plugin.function.invalidResult)此前都回退到 -32603,与 Core 内部失败
plugin.host.failed 共用一个数值,调用方只凭数值分不清。改为 -32070 和
-32071,invalidResult 不再并入 failed;契约 README 与 fixture 同步。
同时删除未被使用的 plugin_functions 访问器。

* fix(toolchain-tests): 测试向量从共享 fixture 读工具 ID,修复 preview 上的宿主语言闸门

- #1752 新增的 toolchain_vectors.rs 写死了 9 处工具名,Verify Host Language Specifics 在 preview 上失败
- 工具 ID 改从 fixtures/toolchains/tool-definition.plugin.json 读取,路径里的工具名换成中性的 tool
- toolchain_resolution.rs 复用 MANUAL_HOME,计数 90 -> 89,基线只调低这一行

* fix(plugin-functions): 中转按会话分道写入,父调用显式关联,上下文失效即结束调用

- 每个目标会话一条写入车道,主工作线程只做规划;停止读取 stdin 的后端只拖住发往自己的写入
- 中转写入有截止时间(会话请求超时),超时后 monitor 让该会话失败(transportFailed/relayWrite)并结束进程
- lithe/host/functions/invoke 新增可选 parentOperationID:指定所服务的调用,调用链和取消只沿这一条走;
  不在调用方会话里运行的父调用返回 plugin.host.cancelled,格式错误返回 invalidParams
- 新快照让调用的工作区上下文关闭或换代时,等待中和运行中的调用都以 plugin.host.contextExpired 结束
- 运行中的调用在截止时间后再给 2 秒宽限,被调方仍不回答则以 plugin.host.timeout 结束并取消被调方
- functionProviderStartRequired 复用已有事件构造函数,新文件不再出现宿主语言词
- Swift 解码失败的 try? 和 Rust 的 let _ = 补 log-exempt 标注
- 契约 README、function-protocol fixture、Note 同步;热激活描述更正
- 新增引擎级测试:阻塞后端不拖住其他调用、父调用限定取消、未知/已结束/格式错误的父调用、上下文关闭或换代

* test(macos): 跨插件调用测试按 #1747 的新目录读取 backend fixtures
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