Repository navigation
feat(plugins): 插件注入的工具链框架与 macOS 只读环境设置页 - #1581
Conversation
技术方案评审:
|
| 贡献 | 回答什么 | 形式 | 谁提供 |
|---|---|---|---|
| 工具定义 | 工具是什么:怎么识别、探测版本、导出环境、启动 | 清单里的静态声明 | 任何插件 |
| 提供方 | 装了什么、项目要什么、全局要什么 | 插件通过 API 返回事实 | 版本管理器插件 |
| 使用方 | 谁需要这个工具 | 已有(通过 tool ID 引用) |
语言服务器、构建系统、运行配置 |
1. 工具定义(示意)
"toolDefinitions": [
{ "id": "java", "displayName": "JDK",
"executables": ["bin/java"], "commands": ["java"],
"version": { "arguments": ["-version"], "pattern": "(?:1\\.)?(\\d+(?:\\.\\d+)*)" },
"exports": [{"name": "JAVA_HOME", "value": "${home}"},
{"name": "LITHE_JAVA_PATH", "value": "${executable}"}],
"pathPrepend": ["${home}/bin"],
"launch": ["${executable}", "${runtimeArguments}", "-jar", "${entry}", "${arguments}"] },
{ "id": "maven", "displayName": "Maven",
"executables": ["bin/mvn"], "commands": ["mvn"],
"projectExecutables": ["mvnw"],
"version": { "arguments": ["-v"] },
"pathPrepend": ["${home}/bin"] }
]这张“工具 ID 到宿主用途”的映射表就是适配层里本来要写死的东西,改成插件贡献。它取代的是:java 当 JDK home 的特判、maven → mvn 的文件名巧合、契约里写死的版本探测参数和 LITHE_<TOOL>_PATH 导出规则、launch.kind: runtime 里 tool 只能是 java 或 node 的限制,以及选择链里专门给 mvnw、gradlew 写的分支。
- ID 归属。 插件自己的工具用
插件id:工具;不带前缀的短名(java、node、go、maven)是保留名,只有宿主内置或官方签名插件能定义。同一 ID 被重复定义时拒绝后来者,不允许覆盖。 - 宿主内置的那几个用同一种格式的数据文件表达,放在
shared/下,各平台随应用打包,作为第一个贡献者注册。适配层里不出现任何工具名,以后各插件可以逐个接管自己的定义。 - 安全校验由 Core 统一做,与具体工具无关。 环境变量值只能是
${home}、${executable}模板;禁止PATH、DYLD_*、LD_*;pathPrepend只能在${home}之内;探测参数必须是-x/--xx形状。安装审查里列出每个定义会运行的程序和参数。
2. 提供方 API
清单只声明“我能回答哪些工具”,不描述目录结构和文件格式:
"toolchainProviders": [{ "id": "mise", "displayName": "mise",
"tools": ["java", "node", "maven", "pnpm", "go"] }],
"permissions": ["toolchains.provide"]宿主向插件发 toolchains/query({operationID, workspace, tools},workspace 为空表示只问全局),插件返回:
{ "installations": [
{"tool": "java", "version": "21.0.2", "home": "/…/installs/java/21.0.2"} ],
"statements": [
{"tool": "java", "scope": "project", "source": "/proj/mise.toml",
"request": "21", "installation": "/…/java/21.0.2"},
{"tool": "java", "scope": "global", "source": "~/.config/mise/config.toml",
"request": "17", "installation": "/…/java/17.0.9"},
{"tool": "node", "scope": "project", "source": "/proj/.tool-versions",
"request": "lts", "installation": null} ],
"watch": ["/proj/mise.toml", "/proj/.tool-versions", "…/installs/java"] }- 插件只能回答自己在
tools里声明过的、且有已启用插件定义的 ID,其余丢弃。这样“任意同名文件被注入”的口子就堵上了。 - 版本语义(哪个文件优先、
lts对应哪个目录)归插件,宿主不解释request。 installation: null表示项目要求了但没装。watch沿用 PR 里“缓存到输入变化”的思路:宿主只做stat指纹比较,没变就不再调用插件。- 沿用现有的
operationID、取消、超时和过期结果规则。 - 返回的路径由 Core 统一校验:绝对路径、存在、可执行、不落在工作区内(保留 PR 现有的这条安全规则)、数量有上限。
.tool-versions、mise.toml这类通用解析函数放进 lithe-plugin-docs 的 Node/Java SDK,不放进宿主。
3. 统一的选择规则
所有工具共用一条规则,按层从上到下取第一个有值的:
| 层 | 内容 | 范围 |
|---|---|---|
| 1 固定 | 用户在 Lithe 里为这个项目选的 | 项目 |
| 2 项目要求 | 提供方上报的 scope: project,以及 mvnw、gradlew 等项目自带的包装脚本 |
项目 |
| 3 全局默认 | Lithe 里的全局默认 → 提供方上报的 scope: global → JAVA_HOME/PATH |
全局 |
| 4 自动检测 | 满足最低版本的已安装最新版(现有的 Core 规则) | — |
- 没装任何插件时,第 2 层为空,行为与现在完全一致。
- Lithe 里固定的值失效:报错,不回落(与调试适配器那篇 Note 的做法一致)。
- 项目要求了但没装:回落到下一层继续工作,但状态标成“未满足”,界面明确提示。
- 界面上每个工具一行,显示“JDK 21 · 来自项目要求(mise.toml)”,展开后列出每层的值,被盖住的划掉。
对这个 PR 的建议
可以保留: 工作区内路径拒绝、按输入缓存、只读原则、i18n 词条、功能矩阵条目、RuntimeChoiceSource 的“来自 %@”展示。
需要重做: Core 里的 toolchain_sources.rs(管理器专属解析与选择语义)、清单 schema 里的目录与格式描述、ProjectRuntimeService 里三条各自的链。
建议拆分:
- 契约(工具定义、提供方、校验)加 Agent Note,先定契约再写代码;
- 适配层的查询客户端(缓存、取消、过期);
- 统一选择规则加运行时设置界面;
- mise 插件加 SDK 帮手,再写一个 SDKMAN 插件当验收,并把
MacRuntimeDiscovery里写死的 SDKMAN 位置迁出去。
契约在 shared/contracts/plugins/v1/,合并后要在 lithe-plugin-docs 运行 node scripts/contract.mjs sync 同步。
待讨论
- API 方向。 上面是“宿主请求、插件返回事实”,不是“插件主动推送”。推送需要插件进程为每个打开的项目常驻;请求式有明确的超时和取消。需要时可以在同一协议上加
toolchains/changed通知。 - 规则细节。 “固定 > 项目要求 > 全局默认”,以及“要求没装就回落并警告”,是建议值,欢迎提出不同意见。
- 保留名。 只允许官方签名的插件或宿主内置定义不带前缀的短名;若允许社区插件定义,冲突处理会复杂很多。
- 自举和免重启。
- 提供运行时的插件,它自己的后端不能依赖它要发现的运行时,否则循环依赖。后端必须自带运行时或是单文件可执行程序(契约已有
packagedRuntime)。 - PR 的
canActivateWithoutRestart只放行“无后端”的插件,这个条件需要放宽。 - 这两点我们还没有原型验证过。
- 提供运行时的插件,它自己的后端不能依赖它要发现的运行时,否则循环依赖。后端必须自带运行时或是单文件可执行程序(契约已有
- Core 的一次性改动。 加定义的校验,以及把
checkRuntimeVersion里 Java 8 的1.x特例改成定义里的正则。之后新增工具或管理器都不再改 Core。
|
这个具体的先后顺序啥的我记得构建工具里面我之前就提过一个方案,按照优先级去维护一个顺序,你可以去看看,具体细节我记不清楚了哎 |
|
感谢这么细的评审。结论先说:同意按「工具定义 / 提供方 / 使用方」重做,本 PR 不再往下推。 我对照代码核对了几处问题,都成立:
你说的「按优先级维护顺序」,我找到的是你在 #1420 的评审(#1420 (comment)):
如果是这条,我打算把新方案的选择规则直接建在它上面,不再写第二套分层逻辑。下面是调整方案,请看方向对不对。 1. 选择规则:写成每个工具定义的默认候选数组四层规则不再写成
示意(Maven;Java 结构相同,把 { "id": "maven", "displayName": "Maven", "commands": ["mvn"],
"version": { "arguments": ["-v"] },
"executables": [
{ "id": "pinned", "kind": "setting", "settingID": "executable", "layer": "project" },
{ "id": "wrapper", "kind": "projectFile", "path": "mvnw" },
{ "id": "projectRequest", "kind": "toolchain", "scope": "project" },
{ "id": "default", "kind": "setting", "settingID": "executable", "layer": "global" },
{ "id": "globalRequest", "kind": "toolchain", "scope": "global" },
{ "id": "home", "kind": "environment", "variable": "MAVEN_HOME", "path": "bin/mvn" },
{ "id": "path", "kind": "command", "command": "mvn" },
{ "id": "detected", "kind": "toolchain", "scope": "installed" }
] }各层在 resolver 里的语义:
这样三条链变成一条。Provider、模型加载和实际执行用同一个结果,#1420 已经保证了这一点。没装版本管理器插件时,所有 2. 提供方:mise 的语义交还给 mise同意「宿主请求,插件返回事实」。mise 插件改成带后端,后端直接调用 mise 自己的机器可读输出,任何一方都不再重写 mise 的规则:
本机验证(mise 2026.9.8):用
自举:后端做成单文件原生程序(Rust,按 darwin-arm64 / x64 分包,Store 已支持按架构下载),不依赖它要发现的 node 或 java。mise 本身的位置用 #1420 的候选声明:设置 → SDKMAN 适合做第二个验收插件: 3. 对待讨论各点的意见
4. 拆分按你的建议,先契约后代码,拆成 4 个 PR:
你列的可以保留的部分(工作区内路径拒绝、按输入缓存、只读原则、i18n 词条、功能矩阵、「来自 %@」展示)会分别带进第 2、3 个 PR。第 1 个提案 PR 提交后关闭本 PR,分支保留作参考;配套的 Store 收录 PR(Lithe-IDEA/Lithe-store#32)同时关闭,等新契约落地后重新提交。 如果方向没问题,我先提第 1 个提案 PR。 |
|
剩下的没啥问题了,你大胆去做吧 |
|
@FxRayHughes 这个可能需要催一下进度,因为有一个 PR 里面我要求使用你这个 PR 的版本管理方案来处理了,如果你没有空的话可以跟我说我来接手 |
改写后的计划:工具全部由插件注入上面几张截图换成了一个可交互的 HTML 原型(链接和用法在最后),以原型和这条评论为准。你 4 个 PR 的拆分和 #1420 候选数组的思路都保留;主要改动是下面这条原则。另外,#1558 的 Maven 迁移要用这里的工具定义来声明 Maven,所以第 1 个提案 PR 请优先提。 0. 原则:宿主不认识任何工具
1. 三类贡献:界面上每一块由谁注入
2. 选择规则:四层,建在 #1420 的候选数组上你在第 1 节给的
3. 按目录(模块)拆分和固定
4. 手动添加
5. 紧凑展示
6. 查询模块和文件监听
7. 拆分(改写后)
你第 3 节里的其余几点照原样进行:免重启第一阶段不放宽, 8. 现有代码里要清掉的写死
9. 原型怎么用
|
* feat(plugins): 声明式语法高亮与运行标记(API-25/27/29) - languages 2:插件语言可带 Monarch 语法和编辑器配置,Core 校验,纯语法插件免重启 - runMarkers 1:backend 2 插件函数回答可运行行,编辑器画运行按钮,点击经 commands/didRun 带 runMarker - 契约、fixture、Agent Note、计划文档与功能矩阵同步更新;Windows 暂不支持 Refs #570 * feat(plugins): 独立编辑器高亮与动作扩展 - languages 2 提供静态语法和独立编辑配置,插件正则在可终止 worker 中运行\n- editor/registerActions 运行期注册文本动作,点击复用普通函数调用,不扩张 Run/LSP/Build/Debug 领域契约\n- 补齐文档版本、动作租约、取消与清理、独立工具后端启用及安全模式边界\n- 更新 Skill、审查规则与决策笔记,总结 #1581/#1558 的架构边界\n- 同步契约、fixtures、中英词条、功能矩阵与资源复用说明\n\nRefs #570\nReworks #1617 * docs(plugins): 明确 API-25 JSON 贡献的支持范围与局限 区分包内静态 JSON 贡献与尚未开放的运行期 Provider 注册、替换和释放;说明独立语义 Provider、新引擎适配及平台、SDK 和验收限制。同步计划、架构笔记、正式契约与功能矩阵。 * fix(plugins): 修复编辑器扩展审查中的生命周期与高亮问题 动作刷新立即确认调度并隔离非致命失败,整批收集共享八秒期限并在撤销时清理计时任务。 Core 保留校验后的 grammar 原始文本,worker 按源顺序解析 cases 并显式默认 root;配置-only 别名借用既有 tokenizer,重映射 token 语言身份以保留独立注释配置。 模块状态观察弱引用 runtime,补齐有界、确定性的 Swift/Rust/WebKit 回归与测试文档模型清理,同步契约、Agent Note 和功能矩阵。 验证:57 项 Swift、1459 项 Rust、39 项编辑器和 119 项真实 WebKit 测试通过;静态边界、i18n、只读 bundle、资源复用与矩阵门禁通过。未执行 Windows 原生构建或打包安装验收。 Refs #1617, #570
27852b0 to
71f9f65
Compare
按 1lck#1581 评审后的改写计划重做:宿主不认识任何工具,工具定义、版本管理器 (提供方)全部由插件声明;Core 只做校验和四层解析,不解析 mise 等管理器 的私有格式。 - 契约:新增 toolDefinitions 1、toolchainProviders 1,executableResolution 增加 v2(只用于工具定义候选);同步 schema、README、toolchains.md、 fixture 和 rust-core-api.md;proposals/toolchains/ 放完整方案草案 - Rust Core:新领域模块 rust/lithe-core/src/toolchain/(定义注册表、 提供方答复校验、目录固定、固定/项目文件/全局/自动四层解析、版本匹配、 扫描计划)和六个 toolchains.* 命令,全部只处理宿主快照,不启动进程、 不扫描、不写文件 - macOS:设置 › 构建新增「运行环境」「环境来源」两页,内容来自已启用 插件的声明和磁盘上的真实文件;未实现的添加、切换、保存、查询入口不显示 - 登录 Shell:新增只读 inspect,来源页显示读取状态、变量数、耗时和 PATH 各目录来源;重新读取不改变本进程 PATH - Debug 预览入口 --toolchain-settings-demo / --toolchain-sources-demo - Agent Note、设置层级 Note、功能矩阵和中英词条同步 Refs 1lck#1514
Lithe Review结论: 未发现需要阻塞合并的问题。 Findings
Scope Check
Suggestions
Summary整体分层与延期边界清晰。建议在后续原生接入前修复上述两处解析不一致,避免设置展示与实际选择产生分歧。 Verification
|
按 1lck#1581 评审后的改写计划重做:宿主不认识任何工具,工具定义、版本管理器 (提供方)全部由插件声明;Core 只做校验和四层解析,不解析 mise 等管理器 的私有格式。 - 契约:新增 toolDefinitions 1、toolchainProviders 1,executableResolution 增加 v2(只用于工具定义候选);同步 schema、README、toolchains.md、 fixture 和 rust-core-api.md;proposals/toolchains/ 放完整方案草案 - Rust Core:新领域模块 rust/lithe-core/src/toolchain/(定义注册表、 提供方答复校验、目录固定、固定/项目文件/全局/自动四层解析、版本匹配、 扫描计划)和六个 toolchains.* 命令,全部只处理宿主快照,不启动进程、 不扫描、不写文件 - macOS:设置 › 构建新增「运行环境」「环境来源」两页,内容来自已启用 插件的声明和磁盘上的真实文件;未实现的添加、切换、保存、查询入口不显示 - 登录 Shell:新增只读 inspect,来源页显示读取状态、变量数、耗时和 PATH 各目录来源;重新读取不改变本进程 PATH - Debug 预览入口 --toolchain-settings-demo / --toolchain-sources-demo - Agent Note、设置层级 Note、功能矩阵和中英词条同步 Refs 1lck#1514
工具的已安装版本有两条途径,可以只用其一或同时使用: - 声明式扫描:工具定义的 discovery/homeLayouts/version 由宿主展开,不运行 插件代码;可用的根和通配写法固定,新的安装形态交给提供方回答。 - 提供方查询:toolchainProviders 通过 toolchains/query 返回安装和要求。 - watchFiles 改为可选:不声明的提供方只报告安装,答复里带版本要求会被拒绝; 定义工具的插件也可以作为自己工具的提供方。 - 自动层把两条途径合成一个候选集合:同一规范化目录只算一次,来源标注优先 提供方、其次 host:system,只用于显示;不同目录同版本仍报冲突。 - discoveryPlan 对每个工具同时列出 scans 和 providers。 - macOS 环境来源页对只报告安装的提供方显示「只报告已安装的版本」。 同时修复评审的两个 P2: - 符号链接安装在解码时已规范化,解析时却按原始路径查证据而误判 unsafePath; 现在文件证据同时证明其规范化目标,证据互相矛盾时拒绝快照。 - 环境变量候选声明的 path 布局被忽略、总取第一个布局;现在按声明的布局选择。
- Core 新增 toolchains.candidates:列出一个工具的登录 Shell home 变量、扫描到的安装、跳过原因和自动层的选择;和 resolve 共用事实校验,宿主分两轮调用完成版本探测,工作区内的目录在探测前拒绝 - toolchains.discoveryPlan 增加 pathPrepend 模板和各平台适用的 home 变量 - 新增 MacToolchainDiscovery:按插件声明展开扫描,只探测 Core 返回的可执行文件;扫描根、条目、文件事实、安装数、探测数、并发和总时长都有上限,超出时给出诊断 - 运行环境页:全局卡片显示 home 变量和探测到的版本,PATH 命令标为版本未验证;自动卡片列出真实安装、选中项、同版本冲突和跳过数,路径显示扫描到的条目名 - 加载器只把登记在官方目录、并经内置或插件市场安装的插件标为官方来源 - 预览改用完整的样例清单,扫描本机真实安装 - 更新契约 toolchains.md、rust-core-api.md、Agent Note、功能矩阵和中英词条
78e696e to
06337dc
Compare
运行环境、环境来源两页插在项目页和运行配置之间,使 SettingsCategory 声明顺序(搜索结果顺序)与侧栏构建分组顺序不一致, settingsCategoryPlacesProjectAndRunBetweenKeymapAndTerminal 在 CI 失败。 把两页的 case 移到项目页之前,测试改为断言 Keymap 与 Terminal 之间 恰好是构建分组,且分组以项目页、运行配置结尾。
test(macos): 设置页声明顺序与构建分组保持一致(修复 1lck#1581 的 macOS CI)
- Core: lsp.toolchainRequest 与 litheToolchains 协商,原样回传回复交 toolchains.decodeReply - Core: candidates 接受 providerInstallations 并保留提供方归属 - 修复别名链接 home 只有链接路径事实时被判 unsafePath(机器人 P2) - macOS: 启动或复用插件后端查询,全局+逐目录独立 operationID/代次,超时与取消 - macOS: watchFiles 与回复 watch 变化整份重查,短时间事件合并 - 设置页显示提供方要求、版本与查询结果;文案走 shared/i18n - 更新契约、功能矩阵与 Agent Note
feat(plugins): macOS 设置页接入工具链提供方查询 (1lck#1581)
|
按上次的分工,补齐了框架剩下的部分。每一项都在单独分支上做,经 fork 内 PR 合入本分支,当前 head 为
本地验证
还没做到的
框架合入后,我再向 Store 重新提交 mise 的索引 PR。 |
- 每个查询过的目录、每个工具调用一次 toolchains.resolve,摘要、徽标和 “第几层生效”都读它的结果,视图不再自己按固定 → 项目 → 全局 → 自动排序 - 解析与提供方查询共用同一份文件事实;同一轮查询的提供方共享代次, 每次查询仍有独立 operationID - 固定值交给 Core 校验:只有固定值的目录只解析它固定的工具(每次加载 最多 256 个),固定的 home 经 toolchains.candidates 检查后探测, 不会出现在自动检测列表;不可用时终止失败,不回落 - 未安装的项目要求记为 unmet 并退到下一层;Core 无法给出结果时给出诊断 - 已知限制写入提案 Note 并建 Issue:冲突选择与写入 1lck#1639、 项目 wrapper 1lck#1640、PATH 命令 commandHomes 1lck#1641 - 新增文案走 shared/i18n 并重新生成
- 同一目录一轮查询里,context 与本轮不一致的提供方回复不会进入 toolchains.resolve, 但它的项目要求仍被写进页面的 requirements,导致页面显示的要求和 Core 的生效结果来自 两个不同的 context;现在只记录进入本轮的回复的项目要求,全局要求和安装列表不变。 - 新增 aReplyUnderAChangedContextIsLeftOutOfItsDirectory 测试:两个提供方在加载途中拿到 不同代次的 context,断言只有进入本轮的提供方要求被显示、Core 用它解析;修复前该测试失败。 - 测试夹具 providerSource 支持声明多个提供方,原有用例行为不变。 - Agent Note 更正“每个路径只读一次”的说法:查询阶段和解析阶段分两次读取事实,单次解析 内部一致;并补充 context 变化时回复不进本轮的取舍。
…lck#1581) - Core 新增 toolchains.failureReply:查询超过 15 秒没有回复,或后端起不来、断开、没有协商这个提供方时,宿主用它生成标准错误回复(plugin.toolchain.timeout / plugin.toolchain.providerUnavailable),再交给 decodeReply,错误码映射只在 Core 维护一份 - toolchains.resolve 只为问过这个工具的查询记 providerUnavailable,并带上 cause 区分超时和不可用;修复一个提供方失败时把它没被问到的工具也记为缺失的问题 - macOS 接线层把 Core 的 requestTimeout 转成 MacToolchainDiscovery.QueryTimeout;取消不生成回复 - 这类回复照常进入目录轮次,下一层来源继续决定;提供方状态显示“15 秒内未响应”或后端原因 - 运行环境页工具行在结果旁写出“mise 未响应 / mise 不可用”,第 2 步在版本文件存在但提供方没回答时显示同样原因,不再显示“版本未查询”;固定值失效时不显示 - 新增中英词条三条;契约 toolchains.md、rust-core-api.md、Agent Note 与功能矩阵同步更新 - 测试:Rust 覆盖两种原因的回复往返、下一层决定、只记被问到的工具、非法输入拒绝;Swift 覆盖超时与后端停止两种提供方并存时的结果与状态
- proposals/toolchains/README.md 文件表里指向 fixtures/ 目录的链接改为代码文本;lithe-plugin-docs 的 contract.mjs sync 要求相对链接指向副本里的文件,这条链接让 #1581 合并后的同步被拒 - verify-shared-contracts.sh 检查契约目录下每个 Markdown 文件(原来只查顶层 README),相对链接必须指向目录内的文件,不能指向目录 - verify-shared-contracts.sh 检查目录下每个 *.schema.json 的 $id 等于 docs 发布地址(原来只查三份顶层 schema) - 更新契约发布 Agent Note,写明两边规则一致的要求和这次被拒的原因
* feat(workspace): enforce directory indexing exclusions (#958) * fix(workspace): honor indexing ownership across Windows roots Fix attached-root LSP gates and reevaluate documents when workspace roots change. Carry request-local ownership through inventory, search, replacement and incremental index caches; preserve scoped search when unrelated roots are unavailable. Disable unsupported remote indexing settings, localize settings failures, normalize both Java exclusion test expectations, and register regressions in Windows CI. * fix(workspace): 修复索引租约生命周期与跨窗口同步 * docs(workspace): 记录复审修复与 macOS 原生验收证据 * fix(lsp): 保留 Windows 冷启动索引策略的原生路径身份 * fix(macos): 保持打开身份并修复索引回归验证 将会话打开代次与资源投影代次分开,保留立即 Run 的等待意图及同根重开隔离。 避免无待确认 Java 决策时重复发布空值,并使设置与混合规则夹具等待真实生命周期边界。 为 Git 观察 CI 补齐逐项报告,按原始输出活性检测 Swift 停顿,保留既有断言与预算。 记录通过的 126 条受影响 Swift 及 116 条身份消费者验证。 * feat(plugins): 独立编辑器高亮与动作 API,复用普通函数调用 (#1617) * feat(plugins): 声明式语法高亮与运行标记(API-25/27/29) - languages 2:插件语言可带 Monarch 语法和编辑器配置,Core 校验,纯语法插件免重启 - runMarkers 1:backend 2 插件函数回答可运行行,编辑器画运行按钮,点击经 commands/didRun 带 runMarker - 契约、fixture、Agent Note、计划文档与功能矩阵同步更新;Windows 暂不支持 Refs #570 * feat(plugins): 独立编辑器高亮与动作扩展 - languages 2 提供静态语法和独立编辑配置,插件正则在可终止 worker 中运行\n- editor/registerActions 运行期注册文本动作,点击复用普通函数调用,不扩张 Run/LSP/Build/Debug 领域契约\n- 补齐文档版本、动作租约、取消与清理、独立工具后端启用及安全模式边界\n- 更新 Skill、审查规则与决策笔记,总结 #1581/#1558 的架构边界\n- 同步契约、fixtures、中英词条、功能矩阵与资源复用说明\n\nRefs #570\nReworks #1617 * docs(plugins): 明确 API-25 JSON 贡献的支持范围与局限 区分包内静态 JSON 贡献与尚未开放的运行期 Provider 注册、替换和释放;说明独立语义 Provider、新引擎适配及平台、SDK 和验收限制。同步计划、架构笔记、正式契约与功能矩阵。 * fix(plugins): 修复编辑器扩展审查中的生命周期与高亮问题 动作刷新立即确认调度并隔离非致命失败,整批收集共享八秒期限并在撤销时清理计时任务。 Core 保留校验后的 grammar 原始文本,worker 按源顺序解析 cases 并显式默认 root;配置-only 别名借用既有 tokenizer,重映射 token 语言身份以保留独立注释配置。 模块状态观察弱引用 runtime,补齐有界、确定性的 Swift/Rust/WebKit 回归与测试文档模型清理,同步契约、Agent Note 和功能矩阵。 验证:57 项 Swift、1459 项 Rust、39 项编辑器和 119 项真实 WebKit 测试通过;静态边界、i18n、只读 bundle、资源复用与矩阵门禁通过。未执行 Windows 原生构建或打包安装验收。 Refs #1617, #570 * fix(indexing): preserve scan ownership and snapshot publication Retry current-workspace indexing cancellation without retiring another owner, publish only the latest complete inventory, and restore saved sessions once per workspace. Apply scoped search before caps and cursors, preserve dotted provider configuration siblings, and normalize Windows mark identity and localized read failures. * docs(indexing): record final macOS native acceptance evidence * fix(search): localize indexing failures and synchronize deferred Run tests * test(macos): synchronize every initial Run inventory release * fix: preserve excluded history and validate indexing marks * fix(macos): 修复分支列表悬停长分支名时触控板无法滚动 (#1621) (#1625) * fix(macos): 修复分支列表悬停长分支名时触控板无法滚动 (#1621) 触控板手势绑定在开始时的窗口上。悬停扩展面板收到首个滚动事件就关闭, 导致同一手势的后续事件全部丢失。手势期间改为隐藏面板并继续转发给列表, 手势结束后再关闭。鼠标滚轮行为不变。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(matrix): 记录分支列表触控板滚动的验证要求 (#1621) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(macos): 手指停顿时保留滚动手势,点击立即回收隐藏面板 (#1621) 手势进行中的回收超时从 1 秒放宽到 10 秒,避免停顿后继续滚动时丢失手势。 隐藏面板收到点击时立即回收,并在功能矩阵补充对应验收步骤。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(macos): remove push dialog file request ordering race --------- Co-authored-by: ZJUSCODE <ZengJun326@outlook.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: Yao Jingxi <23722032@bjtu.edu.cn> * fix(macos): forward hidden branch expansion clicks and clean up on close (#1629) * fix(workspace): preserve directory roles and indexing watcher ownership * test(windows): use canonical roots in indexing lifecycle fixtures * test(windows): identify the owned Run fixture descendant explicitly * feat(macos): 状态栏内存只显示图标,帧率去掉图标并收紧间距 (#1630) - 内存指示器只保留内存芯片图标,不再常驻显示“总计 / Lithe”数值; 悬停提示仍给出总计、Lithe、LSP、服务内存,点击打开原有的托管内存详情, VoiceOver 读出“托管内存”和当前总计。 - 帧率只显示“60 FPS”文字,去掉速度表图标。 - 新增 18pt 的状态栏紧凑图标按钮样式,只读锁和内存图标改用它, 不再沿用 28pt 工具窗口按钮留出的大块空白。 - 删除不再使用的 "Total %@" 词条并重新生成本地化资源。 - 更新 memory-monitor 功能矩阵的 macOS 证据与验收说明。 * fix(macos): 虚拟化后台服务退出列表并补充滚动性能规范 (#1627) (#1633) * fix(macos): virtualize background service exit selection (#1627) * fix(macos): keep background service accessibility selection live * fix(agent): 修复 Codex 会话启动与历史漏查,新增供应商筛选 (#1632) * fix(agent): restore Codex history and add provider filtering * fix(agent): honor manual archive collapse under provider filters * feat(macos): 彩色 LSP 状态菜单与普通日志标签页 (#1631) * feat(macos): 增加彩色 LSP 状态菜单与普通日志标签页 * fix(macos): LSP 入口常驻并仅由启用插件注入服务器 * fix(lsp): 等待重启关闭完成并保留局部索引重置状态 * fix(markdown): preserve inline HTML image layout and alignment (#1623) (#1635) * feat(markdown): render PlantUML diagrams offline on macOS (#1637) * feat(markdown): add offline chemistry formulas and subscripts on macOS (#1636) * feat(macos): 终端标签任意拖拽分屏并保留 PTY (#1638) * feat(macos): 终端标签任意拖拽分屏并保留 PTY - 终端标签改用 AppKit 拖拽会话与私有 pasteboard,避免 Monaco 接收文本拖放 - 工具窗终端可拖入编辑器边缘或空编辑器,编辑器终端可拖回工具窗 - 抽出 EditorGroupLayout.splitting 复用分屏几何,补充模型、拖拽与 PTY 测试 Refs #1622 * fix(macos): preserve terminal drop order and deduplicate split previews - Limit the native tool-window drop overlay to the canvas so tab-strip before/after insertion remains available for terminals dragged from editors. - Publish editor-group preview targets only when they change, including repeated clearing and drag lifecycle cleanup. - Add focused native overlay geometry and preview publication regressions. - Update the docking Agent Note and terminal capability matrix evidence and verification steps without claiming unperformed runtime verification. Validation: six focused Swift tests passed on Swift 6.3.3 with macOS 26.5 SDK; runtime bundle, architecture, i18n, Agent Notes and matrix static gates passed. The exact PR-based push tree also passed the static gates. Refs #1638 --------- Co-authored-by: Yao Jingxi <23722032@bjtu.edu.cn> * fix: align project JDK, isolate application sessions, and improve search (#1642) [skip ci] Use the selected project JDK in JDT configuration on both platforms. Give Windows applications independent cancellable sessions across Run, IDE API and Debug, with isolated failure output. Avoid blocking cold file/text search on content index warmup and improve macOS search sizing and result layout. Include shared fixtures, regression coverage and architecture notes. * feat(plugins): 插件注入的工具链框架与 macOS 只读环境设置页 (#1581) * feat(plugins): 插件注入的工具链框架与 macOS 只读环境设置页 (#1581) 按 #1581 评审后的改写计划重做:宿主不认识任何工具,工具定义、版本管理器 (提供方)全部由插件声明;Core 只做校验和四层解析,不解析 mise 等管理器 的私有格式。 - 契约:新增 toolDefinitions 1、toolchainProviders 1,executableResolution 增加 v2(只用于工具定义候选);同步 schema、README、toolchains.md、 fixture 和 rust-core-api.md;proposals/toolchains/ 放完整方案草案 - Rust Core:新领域模块 rust/lithe-core/src/toolchain/(定义注册表、 提供方答复校验、目录固定、固定/项目文件/全局/自动四层解析、版本匹配、 扫描计划)和六个 toolchains.* 命令,全部只处理宿主快照,不启动进程、 不扫描、不写文件 - macOS:设置 › 构建新增「运行环境」「环境来源」两页,内容来自已启用 插件的声明和磁盘上的真实文件;未实现的添加、切换、保存、查询入口不显示 - 登录 Shell:新增只读 inspect,来源页显示读取状态、变量数、耗时和 PATH 各目录来源;重新读取不改变本进程 PATH - Debug 预览入口 --toolchain-settings-demo / --toolchain-sources-demo - Agent Note、设置层级 Note、功能矩阵和中英词条同步 Refs #1514 * feat(plugins): 工具链安装同时支持声明式扫描与提供方查询 (#1581) 工具的已安装版本有两条途径,可以只用其一或同时使用: - 声明式扫描:工具定义的 discovery/homeLayouts/version 由宿主展开,不运行 插件代码;可用的根和通配写法固定,新的安装形态交给提供方回答。 - 提供方查询:toolchainProviders 通过 toolchains/query 返回安装和要求。 - watchFiles 改为可选:不声明的提供方只报告安装,答复里带版本要求会被拒绝; 定义工具的插件也可以作为自己工具的提供方。 - 自动层把两条途径合成一个候选集合:同一规范化目录只算一次,来源标注优先 提供方、其次 host:system,只用于显示;不同目录同版本仍报冲突。 - discoveryPlan 对每个工具同时列出 scans 和 providers。 - macOS 环境来源页对只报告安装的提供方显示「只报告已安装的版本」。 同时修复评审的两个 P2: - 符号链接安装在解码时已规范化,解析时却按原始路径查证据而误判 unsafePath; 现在文件证据同时证明其规范化目标,证据互相矛盾时拒绝快照。 - 环境变量候选声明的 path 布局被忽略、总取第一个布局;现在按声明的布局选择。 * feat(plugins): macOS 设置页接入声明式扫描与版本探测 (#1581) - Core 新增 toolchains.candidates:列出一个工具的登录 Shell home 变量、扫描到的安装、跳过原因和自动层的选择;和 resolve 共用事实校验,宿主分两轮调用完成版本探测,工作区内的目录在探测前拒绝 - toolchains.discoveryPlan 增加 pathPrepend 模板和各平台适用的 home 变量 - 新增 MacToolchainDiscovery:按插件声明展开扫描,只探测 Core 返回的可执行文件;扫描根、条目、文件事实、安装数、探测数、并发和总时长都有上限,超出时给出诊断 - 运行环境页:全局卡片显示 home 变量和探测到的版本,PATH 命令标为版本未验证;自动卡片列出真实安装、选中项、同版本冲突和跳过数,路径显示扫描到的条目名 - 加载器只把登记在官方目录、并经内置或插件市场安装的插件标为官方来源 - 预览改用完整的样例清单,扫描本机真实安装 - 更新契约 toolchains.md、rust-core-api.md、Agent Note、功能矩阵和中英词条 * test(macos): 设置页声明顺序与构建分组保持一致 (#1581) 运行环境、环境来源两页插在项目页和运行配置之间,使 SettingsCategory 声明顺序(搜索结果顺序)与侧栏构建分组顺序不一致, settingsCategoryPlacesProjectAndRunBetweenKeymapAndTerminal 在 CI 失败。 把两页的 case 移到项目页之前,测试改为断言 Keymap 与 Terminal 之间 恰好是构建分组,且分组以项目页、运行配置结尾。 * feat(plugins): macOS 设置页接入工具链提供方查询 (#1581) - Core: lsp.toolchainRequest 与 litheToolchains 协商,原样回传回复交 toolchains.decodeReply - Core: candidates 接受 providerInstallations 并保留提供方归属 - 修复别名链接 home 只有链接路径事实时被判 unsafePath(机器人 P2) - macOS: 启动或复用插件后端查询,全局+逐目录独立 operationID/代次,超时与取消 - macOS: watchFiles 与回复 watch 变化整份重查,短时间事件合并 - 设置页显示提供方要求、版本与查询结果;文案走 shared/i18n - 更新契约、功能矩阵与 Agent Note * feat(plugins): 运行环境页每行生效来源改由 Core toolchains.resolve 决定 (#1581) - 每个查询过的目录、每个工具调用一次 toolchains.resolve,摘要、徽标和 “第几层生效”都读它的结果,视图不再自己按固定 → 项目 → 全局 → 自动排序 - 解析与提供方查询共用同一份文件事实;同一轮查询的提供方共享代次, 每次查询仍有独立 operationID - 固定值交给 Core 校验:只有固定值的目录只解析它固定的工具(每次加载 最多 256 个),固定的 home 经 toolchains.candidates 检查后探测, 不会出现在自动检测列表;不可用时终止失败,不回落 - 未安装的项目要求记为 unmet 并退到下一层;Core 无法给出结果时给出诊断 - 已知限制写入提案 Note 并建 Issue:冲突选择与写入 #1639、 项目 wrapper #1640、PATH 命令 commandHomes #1641 - 新增文案走 shared/i18n 并重新生成 * fix(plugins): 加载途中 context 变化的回复不再显示项目要求 (#1581) - 同一目录一轮查询里,context 与本轮不一致的提供方回复不会进入 toolchains.resolve, 但它的项目要求仍被写进页面的 requirements,导致页面显示的要求和 Core 的生效结果来自 两个不同的 context;现在只记录进入本轮的回复的项目要求,全局要求和安装列表不变。 - 新增 aReplyUnderAChangedContextIsLeftOutOfItsDirectory 测试:两个提供方在加载途中拿到 不同代次的 context,断言只有进入本轮的提供方要求被显示、Core 用它解析;修复前该测试失败。 - 测试夹具 providerSource 支持声明多个提供方,原有用例行为不变。 - Agent Note 更正“每个路径只读一次”的说法:查询阶段和解析阶段分两次读取事实,单次解析 内部一致;并补充 context 变化时回复不进本轮的取舍。 * feat(plugins): 提供方超时或不可用交给 Core 记为 providerUnavailable,工具行区分未响应与不可用 (#1581) - Core 新增 toolchains.failureReply:查询超过 15 秒没有回复,或后端起不来、断开、没有协商这个提供方时,宿主用它生成标准错误回复(plugin.toolchain.timeout / plugin.toolchain.providerUnavailable),再交给 decodeReply,错误码映射只在 Core 维护一份 - toolchains.resolve 只为问过这个工具的查询记 providerUnavailable,并带上 cause 区分超时和不可用;修复一个提供方失败时把它没被问到的工具也记为缺失的问题 - macOS 接线层把 Core 的 requestTimeout 转成 MacToolchainDiscovery.QueryTimeout;取消不生成回复 - 这类回复照常进入目录轮次,下一层来源继续决定;提供方状态显示“15 秒内未响应”或后端原因 - 运行环境页工具行在结果旁写出“mise 未响应 / mise 不可用”,第 2 步在版本文件存在但提供方没回答时显示同样原因,不再显示“版本未查询”;固定值失效时不显示 - 新增中英词条三条;契约 toolchains.md、rust-core-api.md、Agent Note 与功能矩阵同步更新 - 测试:Rust 覆盖两种原因的回复往返、下一层决定、只记被问到的工具、非法输入拒绝;Swift 覆盖超时与后端停止两种提供方并存时的结果与状态 --------- Co-authored-by: Yao Jingxi <23722032@bjtu.edu.cn> Co-authored-by: FxRayHughes <25192142+FxRayHughes@users.noreply.github.com> --------- Co-authored-by: Xiaoyumuxi <23722032@bjtu.edu.cn> Co-authored-by: ZJUSCODE <152275506+ZJUSCODE@users.noreply.github.com> Co-authored-by: ZJUSCODE <ZengJun326@outlook.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: 十二翼堕落天使 <61737634+icefery@users.noreply.github.com> Co-authored-by: Lichenkang <2188718831@qq.com> Co-authored-by: 枫溪 <bushuaichen@yeah.net> Co-authored-by: FxRayHughes <25192142+FxRayHughes@users.noreply.github.com>
* feat(plugins): execute native build tasks in workspace providers (#1495) * feat(plugins): discover and execute native provider tests (#1495) * feat(plugins): prepare and persist provider application runs (#1495) * feat(plugins): prepare native provider debug sessions (#1495) * feat(plugins): share read-only provider model inputs (#1495) * fix(build): isolate producer revisions and own run saves * refactor(macos): route Agent builds through providers (#1495) * refactor(macos): remove legacy Maven dependency consumers (#1495) * refactor(macos): read project toolchains from canonical storage (#1495) * feat(build): edit native configuration through provider facts (#1495) * feat(build): preserve independent options for each build root * fix(runtime): migrate subproject tool paths to the canonical document * feat(build): resolve canonical toolchains and preserve provider runtime inputs * feat(build): preserve team preferences with sparse local overrides * refactor(runtime): use provider projects and guard Maven data transfer * feat(build): accept provider-owned inline test reports * refactor(java): use current build imports for startup and run preparation * fix(config): preserve malformed local preference sources * feat(config): transfer legacy Maven runtime fields to private defaults * feat(ide): expose native workflows and retire Maven Agent wiring * refactor(maven): retire legacy project service and activate guarded configuration transfer * feat(tests): route exact Java Maven tests through the build provider * feat(run): prepare Java resources through declared provider tasks * test(java): verify Maven Provider resources through real JDT and JVM * fix(java): prepare Run and JDT from the same Provider profile * feat(java): generate Run ownership from current Provider models * feat(maven): generate framework services from effective Provider models * feat(java): consume compiler requirements from current Provider models * feat(maven): consume native Wrapper facts from Provider models * fix(run): reject generated configurations from stale Provider models * feat(maven): prepare services and module runs through typed Providers * feat(maven): prepare JVM service debugging through Providers * docs(maven): record real framework JVM debugging evidence * feat(windows): add workspace Build Provider transport ownership * feat(windows): add current-model Build Provider workflows * feat(windows): read native Build configuration without tool probes * feat(windows): guard native Build configuration writes and readback * feat(build): share team option validation and wire Windows workspace ownership * feat(windows): edit native Build sources through confirmed workspace drafts * feat(windows): present scoped Provider tasks and bounded dependency trees * feat(windows): present canonical Build reports and revoke stale file inputs * feat(windows): observe native Build sources through shared document leases * feat(windows): launch saved Build Provider runs with scoped ownership * feat(build): prepare isolated runs with explicit tool selections * docs: record isolated Run verification results * feat(windows): save Build targets through guarded Run workflows * fix(build): make configuration edits provider owned and reports generic * fix(debug): route provider service attachment through adapter registry * feat(plugins): 插件注入的工具链框架与 macOS 只读环境设置页 (#1581) 按 #1581 评审后的改写计划重做:宿主不认识任何工具,工具定义、版本管理器 (提供方)全部由插件声明;Core 只做校验和四层解析,不解析 mise 等管理器 的私有格式。 - 契约:新增 toolDefinitions 1、toolchainProviders 1,executableResolution 增加 v2(只用于工具定义候选);同步 schema、README、toolchains.md、 fixture 和 rust-core-api.md;proposals/toolchains/ 放完整方案草案 - Rust Core:新领域模块 rust/lithe-core/src/toolchain/(定义注册表、 提供方答复校验、目录固定、固定/项目文件/全局/自动四层解析、版本匹配、 扫描计划)和六个 toolchains.* 命令,全部只处理宿主快照,不启动进程、 不扫描、不写文件 - macOS:设置 › 构建新增「运行环境」「环境来源」两页,内容来自已启用 插件的声明和磁盘上的真实文件;未实现的添加、切换、保存、查询入口不显示 - 登录 Shell:新增只读 inspect,来源页显示读取状态、变量数、耗时和 PATH 各目录来源;重新读取不改变本进程 PATH - Debug 预览入口 --toolchain-settings-demo / --toolchain-sources-demo - Agent Note、设置层级 Note、功能矩阵和中英词条同步 Refs #1514 * feat(plugins): 工具链安装同时支持声明式扫描与提供方查询 (#1581) 工具的已安装版本有两条途径,可以只用其一或同时使用: - 声明式扫描:工具定义的 discovery/homeLayouts/version 由宿主展开,不运行 插件代码;可用的根和通配写法固定,新的安装形态交给提供方回答。 - 提供方查询:toolchainProviders 通过 toolchains/query 返回安装和要求。 - watchFiles 改为可选:不声明的提供方只报告安装,答复里带版本要求会被拒绝; 定义工具的插件也可以作为自己工具的提供方。 - 自动层把两条途径合成一个候选集合:同一规范化目录只算一次,来源标注优先 提供方、其次 host:system,只用于显示;不同目录同版本仍报冲突。 - discoveryPlan 对每个工具同时列出 scans 和 providers。 - macOS 环境来源页对只报告安装的提供方显示「只报告已安装的版本」。 同时修复评审的两个 P2: - 符号链接安装在解码时已规范化,解析时却按原始路径查证据而误判 unsafePath; 现在文件证据同时证明其规范化目标,证据互相矛盾时拒绝快照。 - 环境变量候选声明的 path 布局被忽略、总取第一个布局;现在按声明的布局选择。 * fix(run): generate opaque provider configurations from current targets Continue #1495 and PR #1558 review corrections. Keep provider run snapshots independent of Java imports, preserve generic overrides, and document remaining Maven and toolchain migration. * feat(plugins): macOS 设置页接入声明式扫描与版本探测 (#1581) - Core 新增 toolchains.candidates:列出一个工具的登录 Shell home 变量、扫描到的安装、跳过原因和自动层的选择;和 resolve 共用事实校验,宿主分两轮调用完成版本探测,工作区内的目录在探测前拒绝 - toolchains.discoveryPlan 增加 pathPrepend 模板和各平台适用的 home 变量 - 新增 MacToolchainDiscovery:按插件声明展开扫描,只探测 Core 返回的可执行文件;扫描根、条目、文件事实、安装数、探测数、并发和总时长都有上限,超出时给出诊断 - 运行环境页:全局卡片显示 home 变量和探测到的版本,PATH 命令标为版本未验证;自动卡片列出真实安装、选中项、同版本冲突和跳过数,路径显示扫描到的条目名 - 加载器只把登记在官方目录、并经内置或插件市场安装的插件标为官方来源 - 预览改用完整的样例清单,扫描本机真实安装 - 更新契约 toolchains.md、rust-core-api.md、Agent Note、功能矩阵和中英词条 * fix(run): persist portable provider launch choices Continue #1495 review fixes by preserving exact runtime arguments, opaque entrypoints and declared Build options in Run v2. Keep user directory overrides when saving selectors and use normalized per-run options without changing Build defaults. * Preserve saved identities when migrating Maven Run v2 configurations * test(macos): 设置页声明顺序与构建分组保持一致 (#1581) 运行环境、环境来源两页插在项目页和运行配置之间,使 SettingsCategory 声明顺序(搜索结果顺序)与侧栏构建分组顺序不一致, settingsCategoryPlacesProjectAndRunBetweenKeymapAndTerminal 在 CI 失败。 把两页的 case 移到项目页之前,测试改为断言 Keymap 与 Terminal 之间 恰好是构建分组,且分组以项目页、运行配置结尾。 * feat(plugins): macOS 设置页接入工具链提供方查询 (#1581) - Core: lsp.toolchainRequest 与 litheToolchains 协商,原样回传回复交 toolchains.decodeReply - Core: candidates 接受 providerInstallations 并保留提供方归属 - 修复别名链接 home 只有链接路径事实时被判 unsafePath(机器人 P2) - macOS: 启动或复用插件后端查询,全局+逐目录独立 operationID/代次,超时与取消 - macOS: watchFiles 与回复 watch 变化整份重查,短时间事件合并 - 设置页显示提供方要求、版本与查询结果;文案走 shared/i18n - 更新契约、功能矩阵与 Agent Note * Complete legacy Run import and require opaque Provider selectors * Resolve provider build tools through pinned plugin definitions * fix(run): bind preparation to current build project identity Replace the new Maven reactor projection with opaque build ownership and protect it from document overrides. Preserve provider Java floors before source discovery, admit implemented macOS tool capabilities, retain declared PATH entries, and make the native-configuration fixture valid on Windows. * feat(toolchains): resolve declared Windows build tools with native evidence Add bounded native capture for directory pins, declaration scans and shell candidates; keep provider queries and official origin closed until implemented. Preserve declared exports without inferring tool homes or forwarding inherited secrets. Probe project launchers only for explicit actions that require version evidence. Remove the unhosted Maven JDK alias and replace its fixture with generic tools. Fix all native-configuration staging fixtures for Windows without relaxing path validation. * feat: preserve per-run tools during provider migration * fix: verify Windows publisher evidence and canonical staging paths * feat(toolchains): resolve Windows provider queries through owned Core sessions * fix(toolchains): revoke native preparation with its window and operation * fix(run): bind Provider tool IDs to current native executable evidence * fix(toolchains): distinguish installation dependencies from direct launch * feat(windows): route Agent Build calls through the workspace provider * fix(run): edit and preserve provider runtime choices * fix(debug): honor provider project roots in source selection * test(run): verify inherited provider reset and reuse editor icons * docs: record completed stage D Windows validation * feat(build): persist Windows local options through UI and Agent * feat(windows): connect Provider debug through the installed adapter registry * feat(toolchains): preserve symbolic consumer defaults in native Build resolution * feat(toolchains): add explicit Build preference editing * feat(toolchains): preserve consumer directory tool inheritance * fix(toolchains): keep saved preference scopes editable and current * docs(plan): record the pre-existing RunEntryPointTests deferral failure and its diagnosed path * fix(run): continue Java runs when no build plugin is enabled prepareCurrentProviderGeneration threw CancellationError whenever the build-systems feature was absent, so a javaMain run with no enabled build plugin silently never launched. Skip the Provider model refresh in that case and keep validating provider generation; an enabled plugin whose feature is not active still cancels. Fixes the five deferred-run RunEntryPointTests and corrects the cause recorded in the stage D plan. * refactor(pr-split): keep stage D to macOS and Core; move Windows changes to a separate PR Restore windows/, the Windows CI workflow, the Windows test-stability script and reference, and the Windows declarative plugin host note to the preview base 9e1a270. Feature-matrix Windows entries return to their base state (new capabilities recorded as missing on Windows), and 69 Windows-only i18n messages are removed while shared messages added in this PR are scoped to macOS. Shared contracts, fixtures, the resource reuse manifest and docs/ci-builds.md stay because they describe both platforms. The Windows changes will be restored in a follow-up PR. --------- Co-authored-by: Yao Jingxi <23722032@bjtu.edu.cn> Co-authored-by: FxRayHughes <25192142+FxRayHughes@users.noreply.github.com> Co-authored-by: 枫溪 <bushuaichen@yeah.net>




关联
toolchainSources提交(27852b0)已经从分支上移除。那个提交在 Core 里解析 mise 的版本文件,以及lts、prefix:这类写法;评审时原作者已同意改成「工具定义 / 提供方 / 使用方」三类贡献重做(见 评审讨论)。现在分支基于最新的 preview,共三个提交:框架本身、「两条安装途径 + 评审修复」,以及 macOS 设置页接入声明式扫描。原则
宿主不内置任何工具:Java、Maven、Node 等工具由插件定义,mise、nvm、SDKMAN 这类版本管理器由插件作为提供方接入。Core 只负责校验和按四层解析,不解释任何版本管理器的私有格式。
改动
插件契约(
shared/contracts/plugins/v1/)toolDefinitions: 1(工具定义)和toolchainProviders: 1(提供方声明,需要权限toolchains.provide)。executableResolution增加 v2,只用于工具定义的候选,不改变现有 Build 的候选集合。rust-core-api.md。新增toolchains.md,以及两个 fixture(tool-definition.plugin.json、toolchain-provider.plugin.json)。proposals/toolchains/存放完整方案草案,包括查询协议、local.json、清单贡献和解析结果的 schema 与用例。这些只用于评审,不是可以安装的清单。java、node等)只能由宿主验证过的官方插件定义;<pluginID>:<tool>;toolchains.md新增「Two installation routes」一节):discovery、homeLayouts、version,由宿主展开扫描,不运行插件代码。适合目录结构固定的安装位置。可用的写法固定为三种根(用户目录、环境变量、绝对路径)加单层*通配,以后不再扩充;新的安装形态改由提供方回答,宿主不加新的解析器。toolchainProviders通过toolchains/query返回安装和版本要求,适合注册表、管理器数据库、命令输出这类声明式写法表达不了的位置。watchFiles改为可选。不声明时这个提供方只报告已安装的版本,答复里带版本要求会被拒绝。定义工具的插件也可以同时作为这个工具的提供方,但提供方后端不能依赖它要发现的工具运行。Rust Core(
rust/lithe-core/src/toolchain/)工具链是一个独立的领域。插件清单模块只在准入时调用它做校验。
definitions.rsquery.rspins.rs.lithe/toolchains/local.json的pins,找出最近祖先目录上的固定值resolution.rspaths.rshost:system);多个提供方之间取限定 ID 较小的。这个标注只用于显示,不参与选择。toolchains.discoveryPlan现在对每个工具同时列出scans(要展开的扫描)和providers(声明了该工具的提供方)。toolchains.registry、toolchains.decodeReply、toolchains.resolvePins、toolchains.resolve、toolchains.checkVersion、toolchains.discoveryPlan、toolchains.candidates。它们只处理宿主传入的快照,不启动进程、不扫描目录,也不写文件。toolchains.candidates(第三个提交新增):给设置页用,列出一个工具的全局层和自动层,不解析具体目录。resolve相同(注册表、平台、工作区根、文件事实、probes、systemInstallations、environment等),校验也共用同一段代码(prepare)。{tool, shell, installations, skipped, selected, conflicts}:shell是登录 Shell 里声明过的 home 变量及其版本,installations是通过检查的扫描结果(按版本从高到低、目录已规范化),skipped带稳定的原因码(unsafePath、probeFailed、versionUnsatisfied等),selected是自动层的选择,同版本不同目录时为空并报冲突。probes,可执行文件都报probeFailed;宿主只探测这些可执行文件,再带上{executable, output, exitCode}调第二次。工作区内的目录在探测前就被拒绝,项目里的程序不会被运行。toolchains.discoveryPlan还会带上定义的pathPrepend模板,以及各平台适用的登录 Shell home 变量(environment: [{variable, path}]),宿主不用自己解析可执行文件候选。backend.rs:backend 2 的插件可以由已准入的工具链查询触发启动。unsafePath。现在一条非 missing 的文件证据同时证明它的规范化目标;同一目标的证据互相矛盾时拒绝整个快照。版本探测按解析结果中的规范化可执行文件路径对应。JAVA_HOME)声明的path布局之前被忽略,总是取第一个布局。现在只按声明的布局查找,和 macOS 设置页的行为一致。declarative.rs:清单中的toolDefinitions(最多 32 个)和toolchainProviders(最多 8 个)必须非空,能力声明要精确对应。macOS
watchFiles的提供方显示「只报告已安装的版本」,不检查项目文件。MacLoginShellEnvironment新增只读的inspect,供来源页使用。重新读取只更新缓存和页面显示,不会改变当前进程的PATH。MacToolchainDiscovery):toolchains.discoveryPlan展开三种根(用户目录、环境变量、绝对路径)和单层*通配,跳过隐藏条目,按homeLayouts取第一个匹配的 home,收集文件事实,然后交给toolchains.candidates检查。MacToolchainSettingsLoader)注入扫描器;只有登记在官方插件目录、并通过内置或插件市场安装的插件才标记为官方来源,Core 只对这类插件开放java这样的短 ID。$JAVA_HOME)和探测到的版本;PATH 上找到的命令显示路径,但标为「版本未验证」,不会被运行。卡片太窄时变量和版本自动换成两行。jdk-21.jdk,而不是每个都一样的Contents/Home),悬停显示完整 home。另外还会显示同版本冲突和跳过的数量。--toolchain-settings-demo和--toolchain-sources-demo。预览里只有插件清单是样例(java、maven、node、python 的完整清单,以及 nvm、uv、mise 提供方),工作区文件、固定值、登录 Shell 和本机安装的扫描结果都是真实的。可以用以下参数指定初始状态:--toolchain-demo-directory <目录>--toolchain-demo-expand <工具,…>--toolchain-demo-size <宽>x<高>--toolchain-demo-workspace <路径>文档与其他
2026-10-31-plugin-injected-toolchains.md;在设置层级 Note 里补充这两页属于哪个分组。plugin-injected-toolchains,macOS 和 Windows 都标为 partial / pending;macOS 的证据里加上了声明式扫描和对应的测试。toolchains.md更新状态说明,新增「Settings candidates」一节;rust-core-api.md增加toolchains.candidates一行。Agent Note 补充扫描器的工作方式、上限和设置页的显示方式。尚未完成
以下内容这次都没做,页面上也不显示:
验证
verify-rust-core-comments.sh、verify-rust-core.sh、cargo fmt -p lithe-core --check都通过。toolchain 相关 71 个测试通过,其中新增:watchFiles的提供方只能报告安装;定义插件可以作为自己工具的提供方;toolchains.candidates:第一轮没有探测结果时返回要探测的可执行文件;带上探测结果后列出版本,选择结果和resolve一致;同版本不同目录时报冲突。discoveryPlan带上pathPrepend和各平台的 home 变量。test-stability-macos共 67 个测试,0 个失败,没有超过 1 秒的。MacToolchainDiscoveryTests(新增):用真实的临时目录和真实的 Core,只替换用户目录和探测函数,不运行本机装的任何工具。覆盖:homeLayouts取第一个匹配、隐藏和不匹配的条目不扫描、链接到工作区的条目不探测、只探测 Core 返回的可执行文件、显示扫描到的条目名、同版本冲突、被拒的声明不扫描不探测、通配规则和 Core 一致,以及预览用的样例清单能通过 Core 准入。ToolchainSettingsLoaderTests、ToolchainSettingsFeatureTests、ToolchainSettingsLayoutTestsMacLoginShellEnvironmentTests(13 个)SettingsSearchVocabulary、SettingsSidebarToolchainSettingsLoaderTests新增:只报告安装的提供方会列出、不检查版本文件;watchFiles不是数组时仍然报声明无效。verify-runtime-bundle-immutability.sh、verify-service-boundaries.sh、verify-shared-contracts.shverify-platform-feature-matrix.sh、verify-agent-notes.sh、verify-test-stability.sh/Library/Java)、17.0.19 和 11.0.31(SDKMAN);Node 26.12.1(Homebrew,被选中)和 24.14.0(nvm);全局层$JAVA_HOME为 17.0.19。指向不存在目录的openjdk-*.jdk链接被正确跳过。1180×820 和 1000×760 两种窗口下卡片都不溢出、不折断版本号。