Repository navigation
docs(contracts): 删除工具链契约草案,已实现部分写进正式契约,测试改用内联数据 - #1752
Merged
Merged
Conversation
- 删除 shared/contracts/plugins/v1/toolchains/proposal/ 和 fixtures/toolchains/proposal/ - 已实现的后端协商 litheToolchains、lsp.toolchainRequest、错误回复规则和 11 个稳定失败码写进 toolchains/README.md - 新增 rust/lithe-core/src/tests/toolchain_vectors.rs,pins/queries/resolution 测试改用内联数据 - 同步契约总 README、工具链提案笔记和语言门禁基线
…ains-proposal # Conflicts: # shared/contracts/plugins/v1/README.md
xiaoyumuxi
marked this pull request as ready for review
November 5, 2026 05:23
xiaoyumuxi
added a commit
that referenced
this pull request
Nov 5, 2026
- #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,基线只调低这一行
xiaoyumuxi
added a commit
that referenced
this pull request
Nov 5, 2026
* feat(core): add editor provider decoding and v2 editor actions (API-25, API-27) Core 新增 plugins.editorProviders.decode(注册、结果规范化、definition 合并)并扩展 plugins.editorActions.decode 到 version 2:额外图标、alternatives、点击结果 reveal。 宿主通过 lsp.startServer hostOptions.editor 声明图标、快照上限和路由的 Provider 类型, getCapabilities 回显。未知 Provider 类型返回 unsupportedOption(-32018)。 Refs #1495 * feat(macos): host editor providers and v2 editor actions (API-25, API-27) Refs #1495 - Declare the macOS editor host options (nine gutter icons, 1 MiB action source, seven provider types) and send them in the language-server start options so Core reports them through getCapabilities. - Add the editor.providers permission label and the editor service `lithe/host/editor/registerProviders`: registrations are leased per plugin context, withdrawn on function withdrawal, session end and context close, and limited to 32 per plugin. - Query matching providers concurrently with Core's per-type budgets and drop late, stale, failed or malformed answers; completion triggers only reach registrations that asked for the typed character. - Supplement go-to-definition with plugin locations through Core's merge rule; the language server's answer is never replaced. - Route editor action alternatives and the reveal result of a clicked action to the native navigation list. - Bridge code lenses, document links, hover, completion, folding ranges and semantic tokens to the web editor behind opaque per-batch keys, so plugin targets and lens parameters never come from the page. * feat(editor): draw plugin action lanes and add plugin editor providers (API-25, API-27) Refs #1495 - Plugin editor actions get a left lane for navigation icons and a right lane for run icons, one marker per line and lane. A click opens a menu with each action followed by its alternatives (for example Debug after Run) and posts the opaque action and alternative keys. - Add the nine icon names the macOS host offers plugins with light and dark SVGs, and check that every offered name has an SVG. - Register hover, completion, code lens, folding range, semantic token and document link providers for all languages. They only supplement the language server: semantic tokens apply where no language-specific provider exists. - Draw document links with opaque URLs of a private scheme and open them through a registered opener that asks the host, so a plugin-supplied URL (including command:) never reaches Monaco. - Keep the page rules (range conversion, hover escaping, folding limits, semantic legend merge, action markers and menus) in pure modules with unit tests. * test(macos): cover plugin editor providers and v2 editor actions (API-25, API-27) * refactor(macos): keep plugin definition helpers out of the navigation extension (API-25) AppModel+CodeNavigation grew to 619 lines and tripped the 600-line AppModel extension limit in verify-service-boundaries.sh. The plugin-only helpers (presenting plugin definitions, wrapping link availability) move next to pluginDefinitionQuery. The log-exempt marker for the handled decode failure now sits on the catch line, where verify-log-usage.mjs looks for it. * docs(plugins): record editor provider and v2 editor action decisions (API-25, API-27) Update the plugin API plan rows for API-25/26/27, rewrite the editor extension Note around the shipped provider and action design, and register the editor providers capability in the platform feature matrix (macOS partial, Windows missing). * fix(core): 编辑器 Provider 选择器的语言 ID 不区分大小写(API-25) 契约要求选择器条目不区分大小写匹配,宿主按小写比较语言 ID, Core 解码注册时把 languages 转成小写再排序去重。 同时把两处测试里的 compactMap 移出 #require,避免宏展开后报 call can throw 的编译错误。 * fix(editor-providers): 修复编辑器 Provider 评审问题 - 修饰键悬停只保留最新一次插件定义查询,新悬停取消旧查询并让旧票据失效 - 只读预览不向插件询问定义,跳转前复查文档版本,结果在呈现处再确认仍然有效 - 用户可见错误改走 L10n.string - 修正 EditorHostOptions 的 rustdoc 链接 - 插件编辑器 Provider 在宿主 Provider 之前注册,悬停探针的顺序稳定 * fix(editor-providers): 合并 fixtures 分目录后迁移编辑器 fixtures,导航复用语言服务器准备检查 - editor-providers、editor-actions-v2 fixtures 移入 fixtures/editor/,同步测试、契约脚本、README 和功能矩阵路径 - 转到定义的插件分支复用 languageServerIsPreparing,不在宿主导航代码里新增语言名 - plugin-editor-actions.ts 语言词计数降为 0,更新基线 * 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,基线只调低这一行
This was referenced Nov 5, 2026
xiaoyumuxi
added a commit
that referenced
this pull request
Nov 5, 2026
- #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,基线只调低这一行
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
为什么
shared/contracts/plugins/v1/toolchains/proposal/是工具链重写的设计草案,已实现和未实现的行为混在一起。它被逐字节同步到 lithe-plugin-docs 后,插件开发者看文档时分不清哪些现在能用。草案里已经实现的部分其实只有三块:后端协商、稳定失败码和错误回复规则。这次把这三块写进正式契约,删掉草案和它的 fixture。Core 测试原来读草案 fixture,现在改用内联数据。改动
删除(13 个文件)
shared/contracts/plugins/v1/toolchains/proposal/整个目录:README.md、manifest.md、protocol.md和 4 个 schema(local、manifest-contributions、query、resolution)。shared/contracts/plugins/v1/fixtures/toolchains/proposal/整个目录:java-tool-definition.json、mise-provider.json、local.json、manifest-rejections.json、query-cases.json、resolution-cases.json。fixtures/toolchains/tool-definition.plugin.json和toolchain-provider.plugin.json,这两个是正式清单示例。正式契约
shared/contracts/plugins/v1/toolchains/README.mdplugin-manifest.schema.json为准。## Provider backend negotiation一节,按 Core 现有实现写:initialize的 client capabilities 里带experimental.litheToolchains: {versions:[1], providers:[已排序]}。只有声明了提供者、由插件拥有的会话才会收到。initialize结果的 server capabilities 里回{version:1, providers:[...]},providers必须是 offer 的非空、不重复子集,其他字段忽略。答错一律一个都不启用,不会部分启用。toolchainProviders运行时事件。lsp.toolchainRequest的输入、toolchains/query方法和 Core 自己分配的 JSON-RPC ID。没有选中的提供者直接返回not_supported/plugin.toolchain.providerUnavailable,不写请求。超时取值夹在 1–60000 ms,不传时用会话的请求超时。完成结果是result.value:{id,response}。first/second,不写具体工具名。### Error replies小节,替换原来指向草案protocol.md#stable-failure-mapping的链接:error必须恰好是{code,message,data},data是{code,operationID,providerID}加可选的details。数字码要和data.code对应,两个 ID 要和请求 params 一致。message非空、最多 1024 字节、不含控制字符。details是对象,序列化后最多 4096 字节。违反任意一条都按plugin.toolchain.invalidReply拒绝。rust/lithe-core/src/toolchain/query.rs的rpc_code一一对应。result里报告。toolchain_vectors.rs(用绝对 URL)。契约总 README
shared/contracts/plugins/v1/README.mdtoolchains/proposal/行,以及 fixtures 行中「proposal/存放草案示例」那半句。Core 测试(
rust/lithe-core/src/tests/)toolchain_vectors.rs,作为 pins、queries、resolution 三个测试模块共用的内联数据:HOME、WORKSPACE常量,以及私有的MANUAL_HOME。所有路径都在/opt/lithe-fixtures下,测试既不创建也不探测这些路径。local_pins():与原local.json内容相同,含.、apps/web(手动固定 17.0.12)、.config/tools三个固定。query_request()/query_response():与原query-cases.json的cases[0]相同。error_responses():每个稳定失败码生成一条错误回复。数字码在这里独立列出、不引用query::rpc_code,所以测试检查的是映射本身。mod.rs:注册mod toolchain_vectors;。toolchain_pins.rs:删除fixture()加载函数,改用local_pins()。测试名toolchain_pins_contract_fixture_inherits_the_nearest_ancestor改为toolchain_pins_inherit_the_nearest_ancestor,因为已经不读契约 fixture 了。toolchain_queries.rs:去掉本地的HOME/WORKSPACE和contract("queries")分支,input()改用query_request()/query_response(),错误回复测试改为遍历error_responses()。toolchain_resolution.rs:去掉本地的HOME/WORKSPACE和contract("query")、contract("local")分支,改用共用的内联数据(保留OLD)。Agent Note
.agents/notes/proposed/architecture/2026-10-31-plugin-injected-toolchains.md语言门禁基线
scripts/architecture/language-specifics-baseline.json/toolchains/proposal/条目(对应文件已删除)。toolchain_queries.rs16 → 15、toolchain_resolution.rs91 → 90(内联后计数下降,按 ratchet 规则调低)。验证
cargo test --manifest-path rust/Cargo.toml -p lithe-core --lib toolchain:99 passed,0 failed。./scripts/architecture/verify-shared-contracts.sh:通过。./scripts/agent-notes/verify-agent-notes.sh:通过(210 篇笔记)。./scripts/rust-core/verify-rust-core-comments.sh:通过。./.agents/skills/write-stable-tests/scripts/verify-test-stability.sh:通过。rustfmt --edition 2021。build_systems.rs、declarative_plugins.rs、marketplace_plugins.rs、plugin_editor_resources.rs的 rustfmt 差异是 preview 上原有的,本 PR 没碰。verify-no-host-language-specifics.mjs --base origin/preview:只报新文件toolchain_vectors.rs的 words 0 → 9。这些词来自被删除的local.json和query-cases.json。被删的 10 条草案基线条目合计 177 个计数,加上两个测试文件的 −2,整体净减 170。按维护者决定,本 PR 忽略这一项,不往基线加新条目。合并后要做(lithe-plugin-docs)
本 PR 改了
shared/contracts/plugins/v1/,合并后在 lithe-plugin-docs 的同一个 PR 里完成:node scripts/contract.mjs sync --revision <合并后的 preview commit>。README.md第 163、371 行的toolchains/proposal/目录表行(中英各一)。reference/capabilities-and-versions.md第 112、271 行:litheToolchains的链接改到../contract/v1/toolchains/README.md#provider-backend-negotiation。reference/domains/toolchains.md中文第 121、129–133 行和英文第 260、268–272 行:提案链接和 proposal fixture 列表。reference/protocol-changelog.md第 141 行是 docs(contracts): 插件契约 fixtures 按功能分目录并修正能力版本表 #1747 的历史登记,保持原样。litheToolchains协商和错误回复规则),并在该 PR 描述中提及本 PR 作者请其核对。