Skip to content

feat(plugins): 普通插件可声明 hostIntegration 与短工具 ID,冲突时争用即不归属 - #1763

Merged
xiaoyumuxi merged 2 commits into
previewfrom
feat/1495-community-host-integration-short-tools
Nov 5, 2026
Merged

xiaoyumuxi merged 2 commits into
previewfrom
feat/1495-community-host-integration-short-tools

Conversation

@xiaoyumuxi

Copy link
Copy Markdown
Collaborator

背景

#1754 决定不再区分官方插件和普通插件:Java 插件改为普通插件 io.github.lithe-idea.java-support,签名要求 none,工具短 ID java 保留。要让这个插件能装上并正常工作,宿主还有两处只认官方插件的限制,本 PR 去掉它们(Java 抽离计划 Q1 的两个前置条件)。

改动

1. 语言服务器 hostIntegration 对所有插件开放(Core + 契约)

  • rust/lithe-core/src/plugins/declarative.rs:languageServers[].hostIntegration 不再要求 dev.lithe 命名空间。删掉 validate / validate_host_integration 的 official 参数和 “Host integrations are reserved to official plugins.” 拒绝。宿主不认识的集成名仍返回 plugin.integration.unsupported。
  • 理由:集成是宿主代码,只读取声明插件自己包内的文件,交给该插件自己启动的语言服务器或 Java 子进程(扩展 bundle、lombok agent、test runner、调试),不给插件额外权限。普通插件经用户确认安装后,本来就能运行自带的服务器进程。macOS 的 JDT 集成按 hostIntegrationID 查找,不看插件 ID,所以 Swift 不用改。
  • 契约同步:
    • fixture:删除 invalid-manifests.json 的 “host integration requested outside the official namespace” 用例,改为 Rust 测试 community_plugins_may_declare_a_host_integration,证明社区插件可以声明;
    • schema 描述、plugins/v1/README.md 的 Host integrations 段落和错误码表同步更新。
  • 不在范围内:构建系统的 hostIntegration: maven 仍然只限官方插件,代码和契约都没动。它会随 Maven 迁移整体删除,组织仓库的 Maven、Gradle 插件都不使用它。

2. 普通插件可以定义短工具 ID,冲突时“争用即不归属”(Core + 契约)

  • toolchains.registry 的输入从 {plugins:[{manifest,verifiedOfficial}]} 改为 {plugins:[{manifest}]},宿主不再提供来源证明。
  • 限定 ID <pluginID>:<id> 的前缀必须是插件自己的 ID,插件之间不会冲突,只有短 ID 会冲突。
  • 冲突处理的变化:
    • 以前:只要出现一次短 ID 重复,整批注册就失败,所有工具链定义都失效,设置页只能显示 “Installed toolchain declarations could not be checked”。
    • 现在:被多个已启用插件定义的短 ID 不归任何一方,这些定义都不注册,其余定义照常工作。结果里新增 conflicts: [{tool, pluginIDs}],按 tool 排序,pluginIDs 也排序。
    • 插件 ID 重复仍然整批拒绝。
  • 没有采用“先到先得”或“按插件 ID 排序决定归属”:这两种做法都能让恶意插件抢占 java 这类常用短 ID。
  • toolchains.discoveryPlan 用的是同一个注册表,被争用的工具不会出现在计划里。消费方解析这个工具时,按“没有插件声明”处理。

3. macOS 宿主

  • 删除 ToolchainSettingsPluginSource.verifiedOfficial,以及 MacServiceContainer 里根据 OfficialPluginCatalog 计算它的代码。discover 和 resolve 不再传这个字段。
  • 设置页加载器 MacToolchainSettingsLoader 以前在 Swift 里自行拒绝重复的工具 ID,整页报“声明无效”。现在改为调用 Core 的 toolchains.registry 取得 conflicts:被争用的工具不显示,每个冲突给出一条诊断,提示只保留一个插件启用。诊断文案的中英词条已加入 shared/i18n。冲突怎么判定只由 Core 决定,Swift 只负责读取和显示。
  • Core 调用失败时回退到原来的行为。

4. 文档

  • shared/contracts/plugins/v1/toolchains/README.md、shared/contracts/rust-core-api.md:registry 的输入和输出。
  • Agent Note:
    • JDT 声明式插件 Note:hostIntegration 不再只限官方插件;
    • 工具链注入 Note:短 ID 和冲突规则,以及被否决的备选方案;
    • Java 抽离计划的 Q1 进度。

5. 其他

有意推迟

合并后

  • 在 lithe-plugin-docs 运行 node scripts/contract.mjs sync --revision <合并后的 preview commit>,并在 reference/protocol-changelog.md 登记:hostIntegration 放开、registry 输入去掉 verifiedOfficial、新增 conflicts。
  • 本 PR 没有改插件后端协议,不需要跑 sdk-e2e。

验证

  • cargo test --manifest-path rust/Cargo.toml(lithe-core 全量):2048 个单元测试和其余集成测试全部通过。
  • cargo fmt --check(lithe-core)通过。
  • zsh scripts/architecture/verify-shared-contracts.sh 通过。
  • node scripts/i18n/verify-app-language-localization.mjs、node scripts/i18n/generate-i18n.mjs --check 通过。
  • node scripts/architecture/verify-no-host-language-specifics.mjs:没有上升项;invalid-manifests.json 删掉官方命名空间用例后计数 22→21,已用 --update-baseline 锁定下降。新测试里的集成名和工具 ID 从 fixture 读取,契约 README 的例子用中性的 compiler,没有为通过闸门放宽任何规则。
  • scripts/macos/test/test-macos.sh --filter 'ToolchainSettingsLoaderTests|MacToolchainDiscoveryTests|MacBuildToolResolverTests|MacNativeBuildProviderIntegrationTests':4 个套件 74 个测试通过;9 个需要阶段 D Maven 开发包的集成测试按原有条件跳过。
  • 新增 Rust 测试 toolchain_resolution_contested_tool_id_is_unowned_for_every_consumer:两个插件定义同一个短 ID 时,toolchains.discoveryPlan 的 tools 为空,版本检查返回 rejected,解析结果为 skip / definitionUnavailable;toolchain_definitions 测试覆盖 conflicts 的内容和排序。

- Core:languageServers[].hostIntegration 不再限 dev.lithe 命名空间;
  toolchains.registry 输入去掉 verifiedOfficial,被多个已启用插件定义的
  短工具 ID 不归任何一方,结果新增 conflicts: [{tool, pluginIDs}],其余
  定义照常注册;插件 ID 重复仍整批拒绝。
- macOS:删除 ToolchainSettingsPluginSource.verifiedOfficial;设置页加载器
  向 Core 取 conflicts,被争用的工具不列出并给出 i18n 诊断,provider 胶囊
  同步过滤。
- 契约、rust-core-api、Agent Note 同步;新增 Rust 与 Swift 测试。
@ghfind-review ghfind-review Bot added the review: high ghfind author score; see https://ghfind.com label Nov 5, 2026
@xiaoyumuxi
xiaoyumuxi marked this pull request as ready for review November 5, 2026 07:17
@lithe-code-review

lithe-code-review Bot commented Nov 5, 2026 •

Copy link
Copy Markdown

Lithe Review

结论: ⛔ 有阻塞
范围: preview ← feat/1495-community-host-integration-short-tools · head: 8a1093c

Findings

  1. [P1] 放开宿主集成前,需要隔离各插件的 JDT 运行时
    rust/lithe-core/src/plugins/declarative.rs:2459

    • 实际影响:新放行的社区插件可以改变其他插件使用的 JVM,甚至在自身停用时导致原有 Java 语言服务无法启动。
    • 触发条件:多个插件声明 jdt。MacServiceContainer.swift:418 将包含停用包的 registeredPlugins 交给集成;MacJdtHostIntegration.runtimeHome(in:)(macos/Sources/Lithe/Platform/MacOS/Plugins/HostIntegrations/Jdt/MacJdtHostIntegration.swift:124)取第一个包的运行时,存入所有集成共用的 ProjectRuntimeService。
    • 复现步骤:保留 Java Support,安装排序在它之前的社区插件 com.example.jdt,声明独立语言及 jdt 集成,附带 JDK 17。重启后打开 Java 文件,全局运行时准备会因低于 Java 21 而失败;停用该社区插件仍不能排除它,因为注册列表包含停用包。此前该社区清单会被命名空间检查拒绝。
    • 来源:本次加剧;开放的新输入触发了宿主已有的全局运行时选择逻辑。
  2. [P2] 无工作区时也应保留工具冲突诊断
    macos/Sources/Lithe/Platform/MacOS/Runtime/MacToolchainSettingsLoader.swift:242

    • 实际影响:冲突工具被隐藏,却没有显示原因和涉及的插件,用户无法按提示恢复。
    • 触发条件:未打开工作区时进入“Toolchain Sources”。该页面仍调用加载器,但第 223 行提前返回,跳过新增诊断。
    • 复现步骤:启用两个定义同一短工具 ID 的插件,调用 load(workspace: nil);返回的 diagnostics 为空,提供方的工具标签却已被过滤。新增测试只断言标签,没有检查诊断。
    • 来源:本次引入。
  3. [P2] 工具冲突警告没有对应的统一日志事件
    macos/Sources/Lithe/Platform/MacOS/Runtime/MacToolchainSettingsLoader.swift:244

    • 实际影响:诊断包无法说明哪个工具因哪些插件争用而失效,缺少排障所需的事实。
    • 触发条件:两个已启用插件定义同一短 ID,设置页显示新增警告。
    • 复现步骤:沿此分支读取快照;加载器仅追加本地化字符串,功能模型和视图也只呈现它。registry 返回成功,通用 Core 请求轨迹不会记录 conflicts 内容,不能代替这条警告事件。
    • 来源:本次引入。
  4. [P2] 用户可见行为变化尚未同步功能矩阵
    macos/Sources/Lithe/Platform/MacOS/Runtime/MacToolchainSettingsLoader.swift:159

    • 实际影响:功能矩阵仍要求验证“官方短 ID”,与新规则相反;按矩阵门禁逻辑,该提交范围也会因缺少实质能力记录更新而失败。
    • 触发条件:本 PR 改变插件准入和设置页冲突行为,却没有修改 shared/platform-feature-matrix/features/。
    • 复现依据:该目录的范围 diff 为空;scripts/platform-feature-matrix/verify-platform-feature-matrix-change.mjs:28 要求平台实现变化伴随能力记录变化。
    • 来源:本次引入。

Scope Check

  • 未找到可验证的关联 Issue;按提供的明确需求审查。
  • 已实现社区插件声明放开、短 ID 冲突剔除、确定性排序、契约及共享翻译更新。
  • 复用了现有 Core 注册和解析能力,没有新增并行领域实现。
  • 上述问题均由本次变更引入或加剧,属于本次职责范围;只有 Finding 1 阻塞合并。

Suggestions

  1. 按声明服务器的插件身份绑定、准备运行时,避免跨插件共用首个 JVM;补充双插件及停用插件的回归测试。
  2. 在无工作区的提前返回之前生成冲突诊断,并将其放入返回快照。
  3. 为冲突声明 WARN 目录事件,记录结构化工具和插件身份,并接入生产日志 sink。
  4. 更新工具链及 Java 插件的功能矩阵记录,修正验证动作,未验证的平台保持 pending。
  5. 补充设置页冲突状态的前后截图;当前上下文未提供截图,视觉效果尚未验证。

Summary

Core 冲突算法清晰,相关纯数据测试覆盖了主要解析路径。开放宿主集成后仍沿用全局 JVM 选择,破坏了插件之间的资源隔离,需要先修复。

Verification

  • 静态检查指定提交范围的实现、契约、测试和笔记差异,并追踪注册、发现、解析、设置呈现及 JDT 运行时调用链;未读取生成字符串表正文。
  • 作者报告 Rust 2048 项单元测试及其他集成测试通过,macOS 74 项通过、9 项跳过,以及格式、契约和 i18n 检查通过;本次未独立验证这些结果。
  • 已提供的 head 检查中,仅 Agent Notes 明确成功,其余列出的检查仍排队或运行中。
  • 本次未运行仓库代码、测试或应用,未访问网络。尚缺上述回归场景、日志与矩阵检查结果、运行时 bundle 不变性验证及界面截图。

@xiaoyumuxi xiaoyumuxi added the matrix-exempt Reviewed non-user-visible refactor; skips platform feature matrix update label Nov 5, 2026
@xiaoyumuxi
xiaoyumuxi merged commit 22c14a9 into preview Nov 5, 2026
18 of 23 checks passed
xiaoyumuxi added a commit that referenced this pull request Nov 5, 2026
plugin-manifest.schema.json 中 requiresTools 的描述仍写着短 ID 需要经过验证的官方来源,#1763 已取消这条规则:任何插件都可以定义短 ID,被多个已启用插件定义的短 ID 不归属任何插件。只改描述文字,不改校验规则。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

matrix-exempt Reviewed non-user-visible refactor; skips platform feature matrix update review: high ghfind author score; see https://ghfind.com

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant