Skip to content

feat(plugins): #1495 原生 Provider 工作流与只读工程模型共享 - #1517

Merged
xiaoyumuxi merged 17 commits into
1lck:previewfrom
Mucheen:codex/issue-1495-workspace-capabilities
Oct 28, 2026
Merged

xiaoyumuxi merged 17 commits into
1lck:previewfrom
Mucheen:codex/issue-1495-workspace-capabilities

Conversation

@Mucheen

@Mucheen Mucheen commented Oct 26, 2026 •

Copy link
Copy Markdown
Collaborator

原生 Build/Run 入口此前主要由宿主展开命令,工作区 Provider 即使掌握工程状态,也不能完成构建、测试和应用启动准备。本 PR 为 #1495 阶段 C 补齐类型化执行、测试发现/执行、运行准备、本地运行配置及原生程序调试准备:没有插件页面时,后端也能进入原生工作流,宿主继续管理取消、输出和应用进程。

Refs #1495

功能与行为

  • buildProviders: 2/3/4/5/6 分别增加原生任务执行、测试发现/执行、应用启动准备、原生程序调试准备和只读模型输入。初始化协商 [6, 5, 4, 3, 2, 1];清单能力准入与进程实际协议分别检查,不支持的方法明确拒绝,不转为宿主 CLI 或插件私有函数。
  • 任务和测试计划校验作用范围、当前工程/目标/模型任务、生效选项、附加参数、相对路径和筛选能力。套件、用例与原始参数数组交给 Provider,由选定的上游引擎解释,宿主不增加 Java 扫描、框架探测或另一份工程模型。
  • build.testDiscoveryPlan、build.decodeTestDiscovery 进入 lithe/build/discoverTests。Core 整体校验、排序与去重,身份包含工程和目标;同名测试跨模块保持独立。上限为 10,000 项/32 MiB,非法选择器拒绝整份结果。
  • 构建窗口使用现有共享树按需展示已发现测试,区分加载、空结果、失败与重试;单项运行先重新查验当前清单 ID。源码、配置、选项、插件包和工作区变化撤销旧清单及进行中的发现,改回旧选项也不会恢复过期缓存。
  • build.prepareRunPlan、build.decodeRunPreparation 进入 lithe/build/prepareRun。Provider 负责上游同步、必要构建和启动事实;Core 只校验可移植计划。可执行目标限宿主工具链标识或裸命令,参数与环境有大小/NUL 检查,工作目录必须位于当前实例内,解析符号链接后仍检查边界。
  • build.prepareDebugPlan、build.decodeDebugPreparation 进入 v5 的 lithe/build/prepareDebug:运行声明只引用同包的适配器,后端先构建,再返回程序相对路径、参数、工作目录与环境。Core 校验已有文件和实例边界,拒绝额外的适配器、进程、端口或 DAP 字段;不把 v4 运行计划当成调试计划。
  • debugAdapters: 2 增加受限的目标参数/环境绑定,program、cwd、args、env 由已校验目标提供,准备声明不得用默认参数覆盖它们。macOS 在交接时重查包身份、可执行权限及程序/实例的符号链接,然后通过原有 Registry 和 DAP 会话启动。
  • Build 树与已保存 Provider Run 配置增加 Debug 入口。保存、激活和准备由现有操作协调器及 Build 生命周期管理,停止、工作区、源码、配置、模型和插件变化阻止过期启动;新增会话失败保留原会话,资源仍由调试模块拥有。
  • 调试配置保留明确的 pluginID/adapterID。缺失、停用或不支持请求的适配器在创建传输前拒绝;无源文件目标不再需要伪造后缀选调试器。同语言多适配器共享匹配源码断点,未限制语言的原生适配器接收全部源码;函数、异常、数据断点及重试继续跟随选中身份。
  • Build 树中的 Provider 应用目标先保存工作区文档,再进行准备;保存失败、工作区变化或模型失效不能启动。验证后的计划交给现有 RunService 解析工具链、启动应用、显示输出、停止及处理退出状态。准备是有界 RPC,应用是独立的宿主进程;不支持借此伪装长期服务或多应用编排。
  • Provider 入口可显式保存到已有 .lithe/run/local.json:保存 provider: build.provider 与 extensions.build 中的插件/实例/声明/工程/目标身份、原始参数,不保存 classpath、命令、环境或上次准备结果。首次保存不要求存在 generated.json;重复保存复用 ID,并保留其他配置、项目工具链和其他扩展元数据。
  • 本地配置由 Core 生成文档变更,macOS adapter 检查原文件快照、补齐忽略规则后通过现有原子写入路径保存,再读回并显示真实配置。冲突或读回不匹配明确报告。重启重新查找当前启用的 Provider、模型和目标并重新准备;缺失时不执行旧计划。
  • Run 窗口正确显示 Provider 主运行输出,覆盖选择、清空、保存、停止及重启入口,不因缺少生成配置被引导页遮挡。运行准备至应用结束保持同一个公开操作 ID;底层准备和进程各自按准确身份管理,旧回调不能污染替换进程,旧 ID 不能停止新操作。
  • Agent 的保存配置启动、操作列表、输出、停止和重启使用同一主运行记录;准备中取消、交接后身份、退出结果与旧 ID 失效有原生回归,授权沿用现有入口。
  • 任务、发现、测试和运行准备复用现有工作区 Provider 会话、原生操作槽与生命周期。进度绑定 Core 分配的 wire request ID;取消、超时、崩溃、插件停用/替换、工作区关闭及晚到结果均保留身份检查和资源清理。诊断/报告解码期间仍检查失效。
  • Build Output 复用流式输出、诊断及 JUnit XML/标准测试结果解析,只追加未显示的尾部,覆盖 Unicode 边界。工作区测试报告使用当前模型的子工程,拒绝不新鲜模型和宿主领域报告集成。显式无效的工具/运行时选择不能让 Provider 独立发现另一个工具。
  • 更新清单 schema、Run v2 schema、共享 fixtures、Core API、中文决策笔记、功能矩阵和中英文 i18n 生成结果。无新增产品下载、打包资源或跨工作树共享可变状态;app 与已安装插件包保持只读。
  • 保留原 PR 的提交历史,并合入 preview@ce7098c09 的调试设计文档基线;没有强制推送或覆盖远端历史。

本轮增量:只读模型共享

  • 新增独立 buildModelInputs: 1,生产者通过 modelSharing 显式开放规范化项目、目标、内容目录和选定普通构建选项;消费者声明精确插件/构建系统身份,并要求 Provider 协议 6。
  • build.resolveModelInputs 重新验证已启用来源清单、范围和数据预算,剔除任务、运行计划、设置、optionValues 和未共享选项。缺失来源与 loading/stale/failed 均有明确结果,不自动安装、启动或跨包调用私有函数。
  • 宿主在模型、依赖、任务、测试、发现及运行/调试准备中附带快照;来源模型、选项、构建文件、包或工作区变化立即撤销旧输入。覆盖选项改走再改回、忽略取消的旧回复和后台解析后发布。
  • 补齐 schema、fixtures、API、功能矩阵与剩余迁移的四个大任务计划。无新增产品下载/缓存,快照仅在内存,版本包保持只读。
  • 配套源码已分别提交为 SDK PR #4(已合并) 与 Maven Draft PR #7,不在本仓库差异中。Maven 删除任务/测试命令模板,真实 Maven 扩展仍拥有工程事实;正式 SDK 发布/锁定及旧业务全量迁移另行推进。

本轮 Review 修复

  • 生产者加载用各实例独立的配置代次判断是否过期。兄弟生产者开始/完成正常加载只撤销消费者快照,不再把彼此的有效模型标成 stale;所属选项 ABA、包、文件和工作区失效检查继续保留。
  • Build 树的应用运行在文档保存前进入现有操作槽。保存和 Provider 准备共享同一 ID/任务;保存完成后重查身份和模型,后续任务/测试、停止或工作区/配置失效可撤销保存阶段,忽略取消的旧保存不能取消新运行、清空其输出或启动旧应用。
  • 增加控制回复/保存 gate 的交错回归,覆盖两种模型发布顺序、消费者得到两个 ready 模型、自身选项 ABA、保存时启动新任务/测试、停止/失效及保存成功/失败。

本轮界面补验

真实 SwiftUI/AppKit 视图,使用真实 Core 计划、受控 Provider 回复和进程替身。Build 树通过原生无障碍操作展开测试及目标;Run 截图验证没有 generated.json 时仍能显示输出。深浅主题均已检查。这是同一版本的状态对照,本轮异步修复未调整布局;尚未补 preview 代码基线截图,完整发行包/Windows 验收仍待完成。

场景 浅色 深色
Build 树展开前 截图 截图
已发现测试及 Debug 入口 测试及 Debug 浅色 测试及 Debug 深色
Provider Run 输出 Run 浅色 Run 深色

最新 preview 冲突修复(#1543 / #1548)

  • 合入 preview@9a78c66790f285a78a2229880a1b653c346d9fe8,包含 fix(run): 统一跨平台启动环境、容错扫描与构建事件过滤 #1543 的跨平台启动环境、容错扫描、构建事件过滤与 docs(plugins): macOS 公共 API 与 SDK 文档实施计划 #1548 的 macOS 公开插件 API 计划;保留原 PR 和前轮冲突修复历史,无强制推送。
  • 解决 4 个文件冲突。Rust 运行配置测试同时保留共享扫描/不完整基线诊断和 Provider 配置保存/身份复用两组回归。三份共享翻译源按词条身份合并,扫描不完整警告与 Provider 文案均保留,并统一重新生成;中英文各 9,455 条。
  • 自动合并部分核对生产组合根仍向执行器注入共享启动环境解析,Provider 复用同一执行器;Run 窗口保留扫描不完整提示与无 generated.json 的 Provider 输出。Core 的未知目录保留策略、Provider 本地配置合并、两组命令和 schema 扩展同时保留。
  • 本轮没有新增插件协议、修改 SDK/插件发行锁或改变阶段 C/D 的交付边界。前轮的 Java 包信任、安装引导和 Provider review 修复继续保留。

前轮 preview 冲突修复

验证

最新 preview(9a78c6679)合并验证

  • Rust Core 标准计时 harness 全量 1,347 项通过,最慢 6.416 秒。冲突涉及的共享扫描/不完整基线诊断回归 10ms,Provider 保存/身份复用回归 21ms;环境优先级与未知目录保留回归一并通过。
  • macOS 使用 Swift 6.3.3 编译成功,标准串行计时 harness 773 项/30 组通过,最慢参数化测试 2.541 秒。覆盖 Provider 运行/调试/模型共享、保存配置、Java 安装与包信任、启动环境桥接,以及文档/Git 观察路径。报告 pr1517-latest-preview-macos HTML/JSON/JUnit;无失败或超时。
  • Windows 前端运行配置工具在 macOS 上以 Bun 计时验证 41 项通过;这不代替 Windows 原生运行验收。本轮未重跑 SDK、真实 Maven/LLDB 工具集成或 Windows 实机检查,未修改其协议或发行工件。
  • i18n 35 项回归、9,455 条中英文生成/本地化检查、共享契约、Rust 注释/格式、测试稳定性、166 篇 Agent Notes、服务/Windows 边界、运行时包只读、212 项功能矩阵与精确 base/head 变化门禁通过。没有放宽检查、修改测试期限或增加豁免;本轮测试和后端进程已退出。

前轮验证记录

  • 本轮冲突修复(preview@2cc32e60b):macOS 编译成功;Swift 6.3.3 标准串行计时 harness 559 项/23 组通过,最慢参数化测试 2.557 秒。覆盖 Provider 执行、模型共享、原生调试、保存配置/Run/Agent、真实 Core 桥接,以及合入后的 Java 安装引导和包信任。首轮直接调用底层 runner 时漏传串行参数,出现 24 个等待超时问题;保留失败报告,改用仓库标准入口后上述全部用例通过,未调整源码或等待期限。报告为 pr1517-conflicts-macos-serial HTML/JSON/JUnit。

  • 本轮 Rust Core 全量计时测试 1,338 项通过,最慢 8.015 秒;使用已合并的 SDK 源码对当前合并工作树运行 sdk-e2e.mjs --working-tree --build-workflows,Node、Java、Rust 后端及原生构建工作流 6 项真实 Core/SDK 进程集成通过。SDK 源码工作树保持干净,未修改契约镜像或锁文件;本轮未重跑真实 Maven/LLDB 工具集成或 Windows 实机验收。

  • 本轮 i18n 35 项回归、9,453 条中英文生成/本地化检查、共享契约、Rust 注释/格式、测试稳定性、166 篇 Agent Notes、服务/Windows 边界、运行时包只读、212 项功能矩阵及 base/head 变化门禁通过。测试进程已退出,无本轮应用或 SDK 后端残留。

  • 前轮 review 修复:Swift 6.3.3 标准计时 harness,358 项/15 组通过(pr1517-review-macos HTML/JSON/JUnit)。覆盖执行模块、模型共享、Provider 会话、Build 树、Run/Agent 入口、配置存储和真实 Core 桥接。新增 6 个测试函数共 18 个参数化场景;保存/并行回复回归最慢 6ms,原生视图深浅主题合计最慢 1.272s,无硬超时或失败。i18n、共享契约、运行时包只读、服务/Windows 边界、笔记、稳定性、功能矩阵及实际 PR base/head 变化门禁通过。该轮没有修改 Rust 协议或 SDK,没有重跑此前完整 Core/真实 Maven/LLDB 集成。

  • 合并最新 preview 的 0beb43c936f61e68b983533805d6534a01fdf8b4,解决 schema、调试参数绑定、i18n 和测试冲突,保留语言服务器托管调试端口与远程 attach 契约。修复连接目标的旧测试夹具,补齐合法 attach/connection 声明,不放松生产校验;更新协议说明中的 1–6 版本列表。

  • macOS:Swift 6.3.3 标准计时 harness;最新组合 536 项/21 组通过,报告 stage-c-ready-macos 包含两项真实工具集成与服务状态机、Core 桥接、存储、运行/调试路由、语言服务、实时启停和 Agent 操作身份。

  • 新增生产 MacBuildProviderSessions + 真实 Rust Core + Maven Java SDK 后端集成:不创建插件页面,私有函数为空,完成三模块读取、单模块编译、精确单方法 Surefire 测试和 Core 报告解码;完整插件包 SHA-256/权限前后不变,等待会话释放后清理。

  • 新增公开 Node SDK Provider + Clang + 真实 LLDB 集成:后端编译,Core 校验准备,生产 Registry/stdio 传输启动调试,命中第 4 行断点、读取 main 栈帧,保留带空格参数后继续并以 0 退出。工具显式注入,不改用户工具偏好;失败也按固定 PID/开始时间清理测试进程。独立计时 2.083 秒。本机开发者调试授权经用户明确同意后开启。

  • Core:完整 Rust crate 检查通过,Core 1,336 项单元/集成测试通过;Git Host 7 项、Agent Host 293 项、IDE Host 5 项有独立进程计时;C ABI、链接符号与 9 项 Swift/Git 桥接回归通过;共享 Core verifier 通过。

  • 配套 SDK 本地 117 项测试、TypeScript 调用方和 6 项真实 Core/SDK 进程集成通过;合并 preview 后再跑 6 项进程集成通过。含无页面调用、精确测试、运行/调试前构建、失败、取消清理、工作区隔离及两个后端交换只读公开模型。

  • 历史 SDK CI 的 Node 20、Java 8 单元和当前宿主 58ca81cf66c5c6e281c7df73ac67adb3526174f3 的真实 Core 原生端到端作业通过。该轮因 preview 调试契约镜像漂移失败;后续 SDK lithe 0.1.12 #4 已合并且 main CI 通过。本 PR 契约仍需在宿主合并后同步,正式 SDK 尚未发布。

  • Maven 独立插件本地 59 项回归、3 项隔离开发包检查通过。Java 8 开发 CI 固定 SDK 提交,当前 Maven 与 3.6.3 两组各 55 项计时检查通过(含 3 项打包);开发包不写 dist/正式 SDK 锁。旧锁定 SDK 的正式打包仍失败,须依赖真实 SDK 发布。

  • i18n 回归与 9,451 条中英文生成检查、共享契约、Rust 注释/布局/格式、测试稳定性、164 篇 Agent Notes、Windows 边界、服务边界、运行时包只读、功能矩阵和相对实际 PR base/head 的矩阵门禁通过;没有增加豁免或放宽脚本。

  • HTML/JUnit、CI 工件、失败和复验记录留在忽略的 .artifacts/test-stability/;不提交 SDK JAR、测试缓存或发行包。完整 UI/正式发行和 Windows 实机尚未验收。

转为可评审时的集成修复

范围与配套状态

此 PR 包含 Lithe 宿主/Core/契约改动。Node/Java SDK 与 Maven 插件通过上面两个关联 PR 提交;联调证据是跨仓库结果,不能当作主仓库文件差异。

阶段 C 尚未全部完成:插件自有原生程序已接入既有 DebugAdapter Registry;只读工程事实共享已接入;阶段 C 剩余验收、三仓合并后的契约同步及正式 SDK/插件发布尚未全部收口。Java/JDT 专属协作与调试业务仍在后续迁移范围,必要的最小公共接口缺口须在迁移前明确验证。Maven/Java 官方插件与全部生产消费者迁移、配置迁移及旧服务删除属于后续阶段;本 PR 不关闭 #1495,不宣称 Java/Maven 领域迁移完成。

真实 LLDB 与 Maven 的生产 adapter 集成已通过;Java/JDT、发行包完整界面工作流及 Windows 实机未验收,功能矩阵保持 pending。Windows 不广告原生 Build Provider 宿主能力。最低 SDK 运行时与固定宿主 CI、Maven Java 8 开发 CI 的证据如上,均不代替正式发行验收。

契约合并后再按两仓库规则同步到 lithe-plugin-docs,本次没有直接编辑其 contract/v1/ 或锁文件。阶段 A 的 #1513 与 Java 独立分发 #1483 已合并,本轮保留其完整实现与迁移边界。

@ghfind-review ghfind-review Bot added the review: medium ghfind author score; see https://ghfind.com label Oct 26, 2026
…sue-1495-workspace-capabilities

# Conflicts:
#	macos/Resources/en.lproj/Localizable.strings
#	macos/Resources/zh-Hans.lproj/Localizable.strings
#	macos/Sources/LitheModuleAPI/Plugins/PluginTypes.swift
#	shared/i18n/messages.json
@Mucheen Mucheen changed the title feat(plugins): #1495 原生 Build Provider 任务执行(阶段 C 首批) feat(plugins): #1495 原生 Provider 构建、测试执行与测试发现 Oct 27, 2026
@Mucheen Mucheen changed the title feat(plugins): #1495 原生 Provider 构建、测试执行与测试发现 feat(plugins): #1495 原生 Provider 构建、测试与运行工作流 Oct 27, 2026
@Mucheen Mucheen changed the title feat(plugins): #1495 原生 Provider 构建、测试与运行工作流 feat(plugins): #1495 原生 Provider 构建、测试、运行与调试准备 Oct 27, 2026
@Mucheen Mucheen changed the title feat(plugins): #1495 原生 Provider 构建、测试、运行与调试准备 feat(plugins): #1495 原生 Provider 工作流与只读工程模型共享 Oct 27, 2026
@Mucheen
Mucheen marked this pull request as ready for review October 28, 2026 00:06
@lithe-code-review

lithe-code-review Bot commented Oct 28, 2026 •

Copy link
Copy Markdown

Lithe Review

结论: ⚠️ 有建议
范围: preview ← codex/issue-1495-workspace-capabilities · head: 0eca520

未发现需要阻塞合并的问题。发现两处可由确定的异步调用顺序触发的 P2 问题,建议修复并补充回归覆盖。

Findings

  1. [P2] 使用生产者自身的配置代次判断模型是否过期
    macos/Sources/LitheExecutionModule/Services/BuildSystemService.swift:613–615

    • 实际影响:多个共享模型的生产者并行刷新时,彼此的正常加载会把有效结果标记为 isReloadRequired。随后 resolvedModelInputs 将这些模型作为 stale,不向消费者提供模型;Provider 应用准备也会拒绝过期模型。
    • 触发条件:工作区存在至少两个 sharesModel、按需加载模型的实例,执行构建窗口的整体刷新。该入口会连续调用各实例的 loadModel。
    • 复现步骤:让 A、B 的模型请求分别停在回复 gate。A 开始时捕获全局代次 r1,B 开始时通过 noteModelChanged → invalidateModelInputs 将其增加至 r2。先释放 A,再释放 B:A 因 r2 ≠ r1 被误判为过期,其完成通知又增加全局代次,使 B 也被误判。期间无需修改任何文件、选项或设置。后续检测会保留这个过期标记。
    • 来源:本次引入。新增的 publicationRevision 使用了所有生产者共用的 modelInputRevision;但生产者在当前契约中彼此独立,其他生产者加载不代表本实例配置发生变化。
  2. [P2] 在保存文档前登记 Provider Run 的操作身份
    macos/Sources/Lithe/Models/AppModel/AppModel+RunConfiguration.swift:9–14

    • 实际影响:较早点击的应用运行可以在保存结束后取消较新的构建或测试,并清空其输出、启动旧选择。保存阶段没有进入操作槽,也没有可由后续操作撤销的身份。
    • 触发条件:从 Build 树启动 Provider 应用,文档保存尚未完成时,再启动另一个构建任务或测试。
    • 复现步骤:将应用 A 的 saveAllDocuments() 暂停在保存 gate。此时尚未调用 feature.runApplication,feature.isRunning 仍为 false,Build 树允许启动任务 B。保持 B 运行并释放 A 的保存:这里只检查工作区身份,随后 A 进入 prepareApplication → startRun;startRun 无条件执行 stopRun(),因此 B 被旧操作取消。保存返回前的停止动作同样无法撤销这个未保存句柄的 Task。
    • 来源:本次引入。该 Build 树应用入口是新增路径;服务层的运行 ID 直到保存完成后才建立,无法保护此前的异步阶段。

Scope Check

  • 关联需求:已提供 [Feature] macOS 存量重构计划:清理废弃实现,将 Maven/Java 领域逻辑完整迁入插件后端 #1495 内容。本 PR 明确交付阶段 C 的增量,没有宣称完成或关闭整个迁移计划。
  • 已覆盖范围:类型化任务执行、测试发现与执行、运行及调试准备、Provider 本地运行配置、只读模型输入,以及对应宿主路由、契约和生命周期。
  • 未完成范围:Java/JDT 与旧生产消费者迁移、旧实现删除、正式 SDK/插件发布及合并后的跨仓库契约同步仍属后续工作,不将其作为本 PR 遗漏报告。
  • 上游复用:所检查路径复用现有工作区 Provider 会话、RunService、DebugAdapter Registry、LSP/DAP 和报告解析;未发现新增 Maven/Java 工程事实的并行实现。外仓 SDK/Maven 改动不在本次代码审查范围。
  • 两项 Finding 均定位于本次新增行为及其直接调用链,属于本 PR 的状态与生命周期职责。

Suggestions

  1. 对应 Finding 1:为每个生产者维护独立的配置/发布代次,保留全局代次用于消费者快照撤销。增加两个生产者并行加载、按不同顺序释放回复的回归,确认两者均能成为 ready,并保留现有选项 ABA 失效保证。
  2. 对应 Finding 2:在首次 await 前登记可取消的运行身份,并让后续运行、停止及工作区失效撤销该身份;保存完成后、交接服务前再次校验。增加保存 gate 下“旧应用 A → 新任务 B → A 保存完成”及保存中停止的回归。
  3. 补充 Build 树测试发现、Run 输出与新增 Debug 入口的受影响界面截图;已有界面应提供前后对比。当前提供的上下文没有截图,视觉效果尚未验证。

Summary

契约校验、上游事实所有权和平台资源归属总体与既有架构一致,新增测试覆盖了较多取消、晚到结果和身份替换场景。主要缺口集中在全局快照代次对独立生产者的误伤,以及文档保存尚未进入运行生命周期的窗口;两项均可局部修复,无需扩大重构范围。

Verification

  • 实际检查:固定 base...head 的聚焦 diff,以及相关 head 调用链;重点包括 Rust 构建计划、模型输入、发现/准备解码、Provider 协议,macOS BuildSystemService、RunService、运行/调试入口、Registry、存储桥接、相关测试、共享契约、功能矩阵和决策说明。未将完整文件清单等同于所有文件逐行验证。
  • 已提供证据:作者报告 macOS 536 项、Core 1,336 项及真实 Maven/LLDB、SDK 集成和静态门禁通过;这些是作者提供的结果,本次未独立复验。所附 head Check Run 仍为 queued/in_progress,不能据此认定当前 head CI 全绿。
  • 本次未运行:任何仓库代码、测试、构建、应用、i18n 检查或运行时包只读检查;未访问网络、修改文件或发布评论。
  • 验证缺口:上述两种交错顺序尚无所见回归覆盖;完整 UI、Windows 实机、正式发行及外仓最终同步仍待验收。需补充界面截图,当前视觉效果未验证。

Mucheen and others added 5 commits October 28, 2026 10:56
* feat(plugins): 支持 Java 签名安装与双架构独立发布基础

* feat(plugins): 完成 Java Support 迁移与按需分发入口

* fix(plugins): suggest Java restoration after completed removal
* fix(run): share launch environment and resilient workspace policies

* fix(run): stop shared Java enumeration at its source limit
@xiaoyumuxi
xiaoyumuxi merged commit 6597390 into 1lck:preview Oct 28, 2026
21 checks passed
1lck added a commit that referenced this pull request Oct 29, 2026
* feat(debug): #1210 tcpLanguageServer 调试传输:调试适配器随插件语言服务器运行(Java 迁入插件的第一步) (#1520)

* feat(debug): #1210 tcpLanguageServer 调试传输:调试适配器随插件语言服务器运行(Java 迁入插件的第一步)

debugAdapters 新增 tcpLanguageServer 传输,用于调试服务寄居在同一插件语言服务器里的适配器(Java Debug Server 之于 JDT LS)。该传输没有 launch.process,endpoint 只有 {languageID, command}:languageID 必须是同一插件 languageServers[] 里声明过的,command 限 [A-Za-z0-9._:-]{1,128}。宿主不拉起进程,而是启动该插件的语言服务器,用 workspace/executeCommand 执行 command,把返回值解析成 1…65535 的端口后连接 127.0.0.1。

Rust Core:DebugLaunch.process 改为可选(其他传输仍必填),新增 DebugTransport::TcpLanguageServer 与 DebugEndpoint 校验;programs() 产出 languageServerDebugAdapter,命令变化需要重新批准;debug_adapter_launch_plan 对无进程适配器返回插件语言服务器的启动计划和 debugAdapter 描述符。

macOS:DebugAdapterProcess 换成 DebugAdapterLaunch(host 为 .process 或 .languageServer);MacJavaDebugAdapterTransport 改名 MacHostedPortDebugAdapterTransport,端口来源由宿主注入,不再知道 Java;LanguageToolingSessionManager 新增 startHostedDebugAdapter,校验语言服务器确由该插件拥有,内置 Java 语言服务被拒绝;端口解析抽成 debugAdapterPort(from:)。tcpPort、tcpAnnounced、attach 和 runSelectedRuntime 仍被拒绝,拒绝文案改为只支持 stdio 与语言服务器承载的适配器。

契约与文档:plugin-manifest.schema.json、契约 README、rust-core-api.md、声明草案和 #1210 Agent Note 同步,新增 debug-adapter-language-server 契约 fixture;功能矩阵补充证据与验证说明。i18n:3 条 Java 专属文案改为通用文案,新增 3 条,调整传输拒绝文案,并重新生成产物。

测试:Rust 新增 3 个 Core 测试;Swift 新增解析器、传输、端口解析(16 个用例)与语言服务器归属测试。

* fix(debug): activate hosted language servers and cancel stale adapter starts

* fix(ci): respect runtime boundaries and stabilize native regression tests

* Merge pull request #1534 from 1lck/codex/remove-bot-pr-workflow

chore(ci): remove unused GitHub App Bot PR workflow

* feat(debug): #1210 远程 attach 契约与普通 TCP 生命周期边界 (#1525)

* feat(debug): #1210 tcpLanguageServer 调试传输:调试适配器随插件语言服务器运行(Java 迁入插件的第一步)

debugAdapters 新增 tcpLanguageServer 传输,用于调试服务寄居在同一插件语言服务器里的适配器(Java Debug Server 之于 JDT LS)。该传输没有 launch.process,endpoint 只有 {languageID, command}:languageID 必须是同一插件 languageServers[] 里声明过的,command 限 [A-Za-z0-9._:-]{1,128}。宿主不拉起进程,而是启动该插件的语言服务器,用 workspace/executeCommand 执行 command,把返回值解析成 1…65535 的端口后连接 127.0.0.1。

Rust Core:DebugLaunch.process 改为可选(其他传输仍必填),新增 DebugTransport::TcpLanguageServer 与 DebugEndpoint 校验;programs() 产出 languageServerDebugAdapter,命令变化需要重新批准;debug_adapter_launch_plan 对无进程适配器返回插件语言服务器的启动计划和 debugAdapter 描述符。

macOS:DebugAdapterProcess 换成 DebugAdapterLaunch(host 为 .process 或 .languageServer);MacJavaDebugAdapterTransport 改名 MacHostedPortDebugAdapterTransport,端口来源由宿主注入,不再知道 Java;LanguageToolingSessionManager 新增 startHostedDebugAdapter,校验语言服务器确由该插件拥有,内置 Java 语言服务被拒绝;端口解析抽成 debugAdapterPort(from:)。tcpPort、tcpAnnounced、attach 和 runSelectedRuntime 仍被拒绝,拒绝文案改为只支持 stdio 与语言服务器承载的适配器。

契约与文档:plugin-manifest.schema.json、契约 README、rust-core-api.md、声明草案和 #1210 Agent Note 同步,新增 debug-adapter-language-server 契约 fixture;功能矩阵补充证据与验证说明。i18n:3 条 Java 专属文案改为通用文案,新增 3 条,调整传输拒绝文案,并重新生成产物。

测试:Rust 新增 3 个 Core 测试;Swift 新增解析器、传输、端口解析(16 个用例)与语言服务器归属测试。

* feat(debug): #1210 远程 attach 契约:attach 配置声明 connection 绑定,适配器在远端的设计 Note

- attach 配置的 targetBindings 新增 connection:host+port 或 address,目的地是适配器参数里的点分路径(最多 4 段),可选 pathMappings(objects/first 两种形状)
- 声明期拒绝目的地冲突(与其他目的地、processId/cwd 参数或默认 arguments 重名/包含),运行期 set_argument 只写空位
- debug.adapters.startArguments 支持 connection 目标,校验主机/端口/映射,返回 connection:{host,port,remote};回环只按字面量判断,其余一律 remote:true
- 适配器没有路径映射绑定而目标带了映射时拒绝,而不是悄悄丢弃
- plan 描述符新增 remoteAttach:{pathMappings},宿主据此决定界面,不按适配器名字判断
- 不新增权限,debug.attach 已覆盖;契约 README、schema、rust-core-api、fixture(含 22 条新拒绝用例)、功能矩阵同步
- 新增 Agent Note:适配器运行在远端——经 SSH 的 stdio 调试(仅设计,待确认四项默认选择后再实现),并更新统一调试 Note

* feat(debug): #1210 远程 attach 兼容性审计:路径映射补 dictionary / pairs 两种形状,缺口清单与路线图

按各调试器上游文档核对“附加到远端程序”的参数写法后,路径映射就四种写法:
- objects:对象列表(debugpy pathMappings、delve substitutePath)
- first:唯一一条映射写成两个字符串(js-debug localRoot/remoteRoot)
- dictionary:以 local 或 remote 一侧为键的对象(CodeLLDB sourceMap、PHP pathMappings)
- pairs:二元数组列表,order 为 remoteLocal 或 localRemote(lldb-dap sourceMap)

形状装不下用户给的映射就拒绝,不截断:first 只接受一条(此前只取第一条,与
“不悄悄丢映射”的原则矛盾,属于未发布 API 4 内的行为修正),dictionary 在键的
一侧不能出现同一个根两次,违反返回 debug.target.invalid(target.pathMappings)。
plan.debugAdapter.remoteAttach 增加 maxPathMappings,宿主据此决定最多显示几行。

契约与 fixture:schema 增加两个 oneOf 分支;remote-attach fixture 增加 keyed、
paired 两个适配器(共 6 个);拒绝用例新增 6 条(共 28 条)。

Note:#1210 统一 Note 新增“兼容性审计”,逐个适配器标注“已核对 / 待核验”,列出
G1–G11 缺口(空闲端口占位符、tcpConnect、监听 attach、URI 目标、命令模板等)的
现状、决定和触发条件,并更新后续路线;SSH Note 说明适配器原生映射与 Core 路径翻译
是叠加的两层,远端适配器必须由 Core 翻译。

* docs(debug): separate network paths from TCP lifecycle scope

* feat(debug): #1210 内置汇编级调试:反汇编、指令步进、指令断点、寄存器与只读内存 (#1527)

* feat(debug): #1210 内置汇编级调试:反汇编、指令步进、指令断点、寄存器与只读内存

内核按适配器能力开放汇编级调试,插件只负责启动 lldb-dap/gdb 等适配器;能力快照 supported = 适配器声明 ∧ 已注册扩展 ∧ 已授权。

- 无源码栈帧:栈帧不伪造文件和第 1 行,显示函数名与地址,暂停后自动打开反汇编

- 反汇编:debug.inspect disassemble 与反汇编视图,高亮当前指令,保持最小滚动,剩余不足时向后续读

- 指令步进:debug.execute 增加 granularity,仅适配器声明 supportsSteppingGranularity 时生效;反汇编打开时步过/步入按指令前进,面板头部与按钮提示同步变化,不支持时提示仍按源码行前进

- 指令断点:debug.setInstructionBreakpoints,点击地址栏设置或移除;只属于当前会话,不持久化、不重放

- 寄存器:作用域 presentationHint registers 显示为寄存器标签;宿主不内置 CPU 寄存器表

- 内存:debug.inspect readMemory,接受地址或保存着地址的表达式,从目标前 64 字节读起并分页;目标字节在十六进制和 ASCII 两侧高亮并滚入可见区;右侧显示设置可切换进制、每格字节数、每行字节数、字节序与 ASCII 列;读不到的字节显示为缺失;只读,不开放 writeMemory

- 单步局部刷新:next/stepIn/stepOut/stepBack 保留现有检查数据并原地替换,线程、调用栈、变量、反汇编、内存与 JSON 视图不再整面板清空,变化的内存字节被标出;继续、暂停、结束才清空

- 变量 JSON 视图:修复顶部空白带,key/value 分色高亮

- i18n:新增词条走 shared/i18n 并生成;功能矩阵新增 debug-disassembly(Windows 待实现);设计笔记补充真实 lldb-dap 验证结论

* fix(debug): #1210 guard retained inspection across steps and cancellation

Freeze the old variable tree before the next stop reloads scopes and keep inspection controls read-only until replacement. Retire disassembly and memory callbacks before synchronous cancellation, and reject stale disassembly retries after session changes. Clear retained inspection when transport fails or the session terminates.

Label memory offsets relative to the requested reference, use shared text-input and font owners, and update the owning decision note and platform verification steps.

Add four deterministic regressions reproduced against the original PR. Validation: 152 selected Swift tests and 72 Rust debug tests passed; i18n, shared contracts, platform boundaries, test stability, Agent Notes, matrix gates and runtime bundle immutability passed. Real GUI and Windows runtime validation remain pending.

* feat(debug): #1210 实现普通 TCP 调试连接与有界生命周期 (#1538)

* feat(debug): #1210 implement direct TCP adapter lifecycle

Unify hosted and external DAP byte streams behind a replaceable connection provider; reserve the seam for future network routes without adding proxy or tunnel behavior.

Add explicit endpoint validation, per-connection remote consent, a one-shot launch/attach entry, bounded startup/write buffering, generation-fenced callbacks, and bounded disconnect draining. Keep the debuggee target separate and external resources user-owned.

Cover routing, cancellation, queue limits, cleanup and real loopback Core DAP initialize/attach/disconnect. Update shared fixtures, localization, architecture notes and the platform capability matrix. Windows host and real debugger acceptance remain out of scope.

* fix(debug): #1210 修复 TCP 调试连接评审问题

- 被拒绝或不可达的端口立即以系统原因失败,不再停在 .waiting 等满超时
- 端点发现与建连各自独立计时:发现 120 秒(语言服务器冷启动),建连 10 秒
- 外部适配器会话初始化期限改为 10 秒建连加 10 秒握手,不再抢在建连之前结束
- 连接对话框在连接启动前保持打开,失败原因留在对话框内并保留已填内容
- connectExternalDebugAdapter 返回失败原因,不再静默丢弃请求
- 当前文件没有调试提供方时,"连接调试适配器…"菜单项不可用;主机名先去除首尾空白
- 删除宿主端口传输中无人使用的错误分支
- 补充发现/建连两段期限与真实回环拒绝连接的测试,同步 Agent Note 与功能矩阵

* refactor(debug): #1210 将 TCP 调试连接生命周期下沉到 Rust Core

连接状态转换、取消规则、代次令牌与过期结果拒绝、只结束一次、
建连/写入/排空期限、待发字节与消息预算、单个在途写入,原先都写在
macOS 的 MacTCPDebugAdapterTransport 里,Windows 接入要重写并重新
证明同一套规则。现在这些规则由 Core 的独立状态机持有,平台只做 I/O。

Core(rust/lithe-core/src/debug/transport_lifecycle.rs)
- 与 DAP 协议状态机独立,按 transportId 登记。
- 新增命令 debug.transport.policy / handle / release:平台发送事件,
  Core 返回新代次、阶段、结果和有序效果(发现端点、设置或取消计时器、
  连接、写入、投递数据、关闭、报告失败、通知终止)。
- Core 没有时钟,只决定期限长短和到期后的转换;待发数据只以字节数
  越过 JSON 边界,真实字节、socket 与计时器句柄留在平台。
- 共享 fixture shared/fixtures/debug/transport-lifecycle-v1.json 覆盖
  约 28 个场景,Rust 逐步回放;已登记到 v1-baseline。

macOS
- 新增 RustDebugTransportCore.swift 类型化桥接。
- MacTCPDebugAdapterTransport 只拥有 NWConnection、端点发现任务、待发帧
  字节和系统计时器,并执行 Core 返回的效果;core 参数贯穿托管端口、
  插件和外部端点三条传输,会话初始化期限改读 Core 策略。
- 计时器触发后也释放句柄,避免排空计时器继续持有传输。
- Core 调用本身失败时本地静默拆除并向所有者报告一次。

已接受的行为差异:观察者在错误输出回调里调用 stop() 时,终止通知
现在仍会送达(旧实现把它当作生命周期被替换而吞掉);重启仍会使旧
通知作废。

文档:更新 Agent Note、功能矩阵与 rust-core-api 契约。

* feat(plugins): Java Support 独立分发、迁移与按需安装 (#1483)

* feat(plugins): 支持 Java 签名安装与双架构独立发布基础

* feat(plugins): 完成 Java Support 迁移与按需分发入口

* fix(plugins): suggest Java restoration after completed removal

* docs(plugins): inventory Maven and Java migration for #1495 (#1513)

* fix(run): 统一跨平台启动环境、容错扫描与构建事件过滤 (#1543)

* fix(run): share launch environment and resilient workspace policies

* fix(run): stop shared Java enumeration at its source limit

* docs(plugins): plan macOS public APIs and SDK documentation (#1548)

* feat(plugins): #1495 原生 Provider 工作流与只读工程模型共享 (#1517)

* 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

* feat(plugins): Java Support 独立分发、迁移与按需安装 (#1483)

* feat(plugins): 支持 Java 签名安装与双架构独立发布基础

* feat(plugins): 完成 Java Support 迁移与按需分发入口

* fix(plugins): suggest Java restoration after completed removal

* docs(plugins): inventory Maven and Java migration for #1495 (#1513)

* fix(run): 统一跨平台启动环境、容错扫描与构建事件过滤 (#1543)

* fix(run): share launch environment and resilient workspace policies

* fix(run): stop shared Java enumeration at its source limit

* docs(plugins): plan macOS public APIs and SDK documentation (#1548)

---------

Co-authored-by: Lichenkang <2188718831@qq.com>
Co-authored-by: Xiaoyumuxi <23722032@bjtu.edu.cn>

* fix(macos): 修复 Java 启动竞态、插件启动参数与无限重试 (#1526)

* fix(macos): stabilize Java startup and plugin launch (#1523, #1524)

* test(macos): bound language startup regression task waits

* test(macos): allow disk image creation margin within integration budget

* fix(macos): revoke deferred language activation when project session closes

* test(macos): cover production language launch and navigation evidence

* fix(ide-host): include ttlMs and cacheScope in MCP tools/list (#1545) (#1546)

The helper advertises protocol revision 2026-07-28 through server/discover.
For that revision ListToolsResult extends CacheableResult, where ttlMs and
cacheScope are required, but building the result with ..Default::default()
left both fields absent. Clients validating the negotiated wire shape
rejected the whole server with INVALID_RESULT (ZCode 0.17.0, Qoder).

The catalog describes live IDE state, so the result is immediately stale
(ttlMs 0) and private to the connected client.

Co-authored-by: jiaqizhang258 <321343564+jiaqizhang258@users.noreply.github.com>
Co-authored-by: Lichenkang <2188718831@qq.com>

* fix(mcp): 稳定 Windows 请求调度与授权生命周期 (#1549)

* fix(mcp): stabilize Windows request delivery and protocol discovery

* fix(mcp): recover independent notifications and enforce monotonic deadlines

* fix(macos): 独立多 Diff 标签与连续滚动、工作树管理体验 (#1555)

* fix(macos): support independent diff tabs and continuous Git browsing

- isolate diff sessions, editor groups, focus, navigation and async reads
- auto-load disassembly, Git/worktree history, VCS and MCP discovery lists
- preserve scroll anchors and suppress background Git command noise
- add worktree change management and shared localized actions
- organize develop-lithe guidance in Chinese and update capability records
- repair per-toolchain SwiftPM resource caches and add regression coverage
- align affected macOS code with the pinned Swift 6.3.3 compiler

Refs #1210

* fix(macos): 工作树更改页即时暂存、工具栏精简与 Git 控制台取消过滤

工作树「更改」页
- 勾选复选框后立即显示目标暂存状态(乐观显示),Git 完成后以实际结果为准;
  仅等待本工作树状态扫描完成即恢复可点击,不再被全项目刷新阻塞。
- 工具栏只保留有实际动作的按钮:刷新、暂存全部、丢弃所选、显示 Diff;
  移除灰显无作用的占位按钮,启用条件与选区/可暂存项一致。
- 提交历史页脚在加载中/失败/空闲都有固定行高内容,不再留空白带。
- 概览动作改为自然宽度的单一换行流,宽窗口详情自适应两列。

Git 控制台
- 在任何命令启动前就被取消(被后续请求取代)的请求不再显示为失败行;
  已启动命令的取消仍保留并标注原因。同步更新共享契约、fixture 与 Windows journal。

其他
- Git Log 筛选弹窗/图/Diff 的布局与滚动细节调整,补充对应测试与中英词条。
- 同步 git-worktrees 平台能力记录。

* fix(macos): 修复多 Diff 标签刷新、历史重试、反汇编宽度与保存更改比较的评审问题

- 状态刷新只在本次真正读取过状态的仓库内才把"缺席"当作文件已干净;链接工作树的标签不再被
  工作区刷新误关,由该工作树自己的状态读取(refreshWorktreeChanges)决定是否关闭
- 工作区/目录比较刷新内容未变时不再给会话的 @published 属性赋值(不重绘、不丢滚动位置);
  新增 GitRepositoryDiffSession.updateDocument,同时比较补丁与行(与 HEAD 的比较没有补丁文本)
- 目录比较刷新改为就地更新(showDirectoryDiff 增加 refreshingConfirmedRoots),不再清空行并闪现加载态
- 提交历史加载失败后的显式重试按已加载条数重新打开窗口,不缩回首页、不移动选择
- 反汇编列表只对最长候选行做文字测量,不再每次 body 求值都测量全部行
- 保存更改比较恢复"快照属于当前仓库"的校验,并在打开标签前校验版本与文件,避免留下空标签
- 补充回归测试,并更新两份 Agent Note

* fix(remote): #1507 远程工作区、构建与插件执行适配 (#1515)

* fix(remote): adapt workspace I/O and plugin execution for #1507

* fix(remote): continue #1507 common backend lifecycle and plugin validation

Integrate PR #1515 onto the preview baseline, preserving plugin live activation and shared i18n changes. Reserve pending process, terminal and watch starts before dispatch; retain cleanup ownership across cancellation, worker saturation, disconnect and session shutdown.

Add deterministic lifecycle and declarative remote launch regressions; isolate the empty connection registry test, fix Swift fixture shadowing and synchronize terminal resize with shell readiness. Update contracts, Agent Notes and partial/pending capability evidence. Java/JDT integration remains out of scope.

* fix(remote): own plugin snapshots and isolate upload I/O

Add session-owned run directory allocation and cleanup with retryable errors, original-session macOS deployment cleanup, and per-upload I/O isolation.

Cover lifecycle and upload ordering regressions, update contracts/resource boundaries and capability evidence, and record optional transfer/environment candidates without expanding Agent or Java scope.

* fix(remote): preserve repository identity and consolidate remote crate

Keep remote Git repository roots and external metadata bound to their original host, including parent repositories and symlink roots.

Consolidate client, protocol and server into lithe-remote with isolated client/server features, preserving the standalone server binary. Update consumers, packaging, CI selection, resource validation, contracts and regression coverage.

* fix(remote): 修复合并后的 Agent Notes 路径,补齐能力矩阵并收紧远程扫描失败判定

- 两条 proposed 笔记的适用范围仍指向已合并的 rust/lithe-remote-client,
  改为 rust/lithe-remote/src/client/,修复 Verify Agent Notes。
- 能力矩阵:remote-development-workspace 增加 BuildSystemService 与共享扫描证据,
  写明运行配置发现尚未接入远程(Core 对 runConfig.inspect 返回 NotSupported,
  仅 runConfig.selectJava 可用);run-discovery 增加同一说明。状态不变。
- 远程共享运行扫描只在链路取消、超时或中断时整体失败;主机对单个目录报告的
  错误仍记为扫描不完整,与本机一致。判断集中到 workspace_io::is_transport_failure,
  detectors/scan.rs 与 workspace_scan.rs 共用,修正此前两处不一致。
- 新增集成测试:读取主机目录树且占位目录保持为空、单目录错误记为不完整、
  根目录之下链路中断时扫描失败。

* fix(macos): avoid reentrant workbench hit testing (#1542) (#1557)

* chore(scripts): 按作用语义整理 scripts 目录层级 (#1563)

* chore(scripts): 按作用语义整理 scripts 目录层级

把 scripts/ 根目录下 127 个平铺脚本移入分类子目录,根目录不再放任何脚本。
全部使用 git mv,历史可追溯。

新目录:
- ci/{common,cancel-closed-pr-runs,update-repo-charts}:CI 脚本,按工作流名分目录
- macos/{build,package,prepare,test,verify,perf,probe}
- windows/{build,prepare,package,test,verify}
- release/{sparkle,macos,autobuild,windows,notes}
- rust-core、architecture、i18n、agent-notes、platform-feature-matrix、
  plugins、remote、ide-mcp、editor、git-graph、agent、resources

同步修改:
- classify-ci-changes.sh 路径模式、plan-ci-lane-reuse.mjs 基础设施规则、
  对应测试夹具(夹具复制脚本时按新目录深度建目录)
- ci-macos.yml 的 scripts/**/*.sh 循环、verify-i18n.yml 等工作流路径与 paths 过滤
- sparkle 的三个 Ruby 脚本改为 require_relative "../autobuild/autobuild-identity"
- tauri.conf.json 的 beforeDevCommand / beforeBuildCommand
- README、docs、Agent 笔记、Skill 和 Fonts NOTICE 中的脚本路径
- develop-lithe Skill 新增“脚本放置与分类”一节,AGENTS.md 增加入口提醒:
  脚本必须在 scripts/ 下按作用分类,不得放在 scripts/ 根目录

验证:
- 127 个脚本在旧分类器/新分类器下的 lane 结果一致,未知路径仍然 fail closed
- 127 个脚本的规划器基础设施规则一致
- 受影响的 node/bun/shell/ruby/python 测试与 i18n、特性矩阵、Agent 笔记、
  共享契约、模块/服务/编辑器边界、运行时 bundle 只读校验均通过

* fix(scripts): 修复 scripts 分类整理的评审问题

- Windows 前端安装测试移到 scripts/windows/build/,与被测脚本同目录,
  测试夹具里复制脚本的路径、ci-windows.yml 的运行命令、分类器 windows 分支
  和 Agent Note 里的路径同步更新
- 分类器空分支删除 3 个已不存在的平铺脚本名,避免过期名字被误当成已登记
- 规划器的 Windows 规则改为按目录匹配(windows/、release/windows/),
  并单独登记 ide-mcp/build-windows-ide-mcp.mjs,补齐测试期望,
  与分类器的路由保持一致
- develop-lithe Skill 补充:平台专属脚本留在所属跨平台领域目录的例外、
  手工验收脚本放 test/、tauri.conf.json / package.json / official-plugins.json
  inputPaths / worktree-resources.json 里硬编码脚本路径的检查清单

* fix(windows): 补全 JavaSelectionRequest.requirements,修复 Windows 安装包构建 (#1507) (#1565)

#1515 给 lithe-core 的 JavaSelectionRequest 新增了必填字段 requirements,
但 Windows 的 select_project_java 仍按旧字段构造,导致 Release AutoBuild
的 Windows 安装包步骤报 E0063 编译失败。

- windows/tauri/src-tauri/src/run.rs:Windows 传 root,requirements 与 root
  互斥,所以填 None
- develop-lithe Skill:补充 lithe-core 公开 Rust 类型/签名也是兼容面,
  Windows 直接链接 Core,改动时要同步检查调用点并给出检查方法

* docs: refresh WeChat community QR code (#1569)

---------

Co-authored-by: Xiaoyumuxi <23722032@bjtu.edu.cn>
Co-authored-by: muchen <145200703+Mucheen@users.noreply.github.com>
Co-authored-by: arkleselect <166632698+arkleselect@users.noreply.github.com>
Co-authored-by: jiaqizhang258 <549728022@qq.com>
Co-authored-by: jiaqizhang258 <321343564+jiaqizhang258@users.noreply.github.com>
xiaoyumuxi added a commit that referenced this pull request Oct 30, 2026
* docs(plugins): 按 preview e8c4e9f 刷新 macOS 插件 API 计划

#1517(原生 Provider 工作流)和 #1515(远程工作区适配)都已合并,
计划里"在途/未合并"的说法已过时。本次只改文档,不改运行时代码、
schema、SDK 和功能矩阵状态。

基线与现状
- 盘点基线:Lithe 更新为 preview e8c4e9f;#1517 记为已合并;新增 #1515
  (阶段性实现,范围与缺口见 API-40);记录插件文档仓库 main 仍是
  be779d2000e3,且其契约锁落后主仓库 4 个触及 plugins/v1 的提交
- 能力版本:对照 PluginTypes.swift 与 capabilities.rs,补上
  buildProviders 1–6、buildModelInputs 1、debugAdapters 1/2;
  Core 与 Mac 唯一差异是 serverProcess(Core 1/2,Mac 1)
- API-29、API-31、API-35、M4、DOC-12、5.1 SDK 行:去掉对 #1517 在途的依赖,
  改为已合并后的文档、SDK 对齐与端到端验收

新增条目(编号接续 API-39,不改动既有编号)
- API-40 工作区 authority(M0):远程工作区仍是本机空占位根,backend:1 与
  Web bridge 不识别远程绑定;未实现的 authority 必须明确拒绝。API-05、
  API-35 同步指向它
- API-41 激活事件与启动预算(M0/M1):现有 activationEvents 只与已声明的
  Provider/窗口命令一一对应;应用没有工作区信任概念,M0 需决定
- API-42 内置 Git 只读快照(M3):Git 不在统一 VCS 层,API-31 只覆盖插件 VCS
- API-43 documents.onWillSave(M3):保存路径没有保存前钩子
- API-44 Agent 侧贡献(后续):Skills/Hooks/MCP 是用户管理的原生配置,
  没有插件来源
- 同步 2.1 现状表、4.1/4.2 评审清单、阶段表 M0/M1/M3c/M4/后续、
  DOC-02/04/07/13 以及新增 DOC-18/19、来源索引 S20–S22

公共扩展契约提案(proposed Note)
- 修正"内置 Git 与插件 VCS 共用同一统一模型",与 2026-10-22 评审一致:
  Git 暂不接入统一层
- #1517 改为已合并,补 #1515 的范围;新增 authority/激活/保存前事件/
  Agent 侧贡献一节,说明本 Note 不预设答案

* 插件后端 2 与函数协议 3:工作区上下文、能力发现与宿主错误码

- requires.backend 新增版本 2:可由 onWorkspaceOpen 或插件命令启动,不再必须有网页;后端可以是插件唯一内容;backend 1 语义不变
- 新权限 workspace.metadata(仅 backend 2)授予 workspace 宿主服务;拒绝 onStartupFinished 等常驻启动事件
- 插件函数协议新增版本 3:lithe/host/getCapabilities 由 Core 直接回答,subscriptions/dispose,workspace/listContexts、getContext、getFolders
- 宿主方法改为表驱动(HOST_METHODS),后续文件、编辑器、窗口服务按行接入
- lsp.functionRequest 可携带 context,仅 v3 后端收到 params.context
- lsp.hostResponse.error 可带 code,按白名单映射为 contextExpired、authorityUnsupported、versionConflict、limitExceeded、cancelled、timeout 等
- 后端可用 $/cancelRequest 取消自己的宿主请求,Core 立即回复 cancelled 并发出 hostRequestCancelled 事件
- 同步契约 README、manifest schema、正反例 fixture 与 Rust 单元测试

* feat(macos): 插件后端 backend 2 的工作区上下文、激活事件与宿主服务分发

- hostCapabilities 提供 backend [1, 2]
- 新增 PluginWorkspaceContexts:每窗口一个上下文,contextID 加 generation,本地/远程 authority,rootID 与状态目录摘要
- 新增 PluginHostServiceDispatcher 与 PluginHostServiceHandling 扩展点,统一错误码、授权与上下文核验、订阅回收与宿主请求取消;凭据与 workspace 服务接入
- MacPluginBackendSessions 支持 onWorkspaceOpen 与 onCommand 激活(串行、不阻塞),调用携带工作区上下文
- RustCoreBridge 传递 lsp.functionRequest.context 与 hostResponse.error.code,会话处理 hostRequestCancelled
- 新增界面文案词条并重新生成;新增 Agent Note 记录设计、第 4 节回答与威胁模型,写明工作区信任暂不引入

* test(macos): 补上上下文测试缺少的 throws 声明

* feat(macos): 为插件 API-09/10 提供宿主内部文档与编辑器服务

实现 macos-plugin-api-plan 中 API-09(documents.list/getSnapshot、
editor.getActive/getSelections)和 API-10(editor.applyEdits/
replaceSelections/insertText)的 Mac 宿主内部服务,暂不对插件公开,
等 M0 分发层接入。

- EditorDocumentService:调用方必须显式传入窗口与工作区范围和文档 ID,
  不回退到当前活动窗口;读取的是含未保存修改的内存缓冲区。
- 新增 EditorDocument.contentVersion 作为版本来源:每次文本变化单调
  递增,不受保存/冲突决策改写,没有 WebView 时也存在,WebView 重载
  后不归零。
- 坐标:行、列都从 1 开始,列按 UTF-16 码元计数;CR/LF/CRLF 各算
  一次换行。只在 LSP 适配边界换算成从 0 开始。
- EditorTextEditPlanner 先校验整批编辑(越界、反向、拆开代理对、
  重叠),全部通过才下发;插入的换行沿用文档首个换行符。
- Monaco 适配:同步比对桥接 revision;JS 端再核对 revision 和未确认
  输入,有 IME 组字、只读、冻结或关闭中时拒绝;用前后两个 undo stop
  加 pushEditOperations 作为一个撤销步骤应用;编辑消息带 origin,
  用来回报这一批产生的精确版本。
- SourceText.apply 支持按批次指定 EOL。
- 补充 Swift 单测(emoji、组合字符、CRLF、中文、多选区、版本冲突、
  只读、越界、重叠)和 bun 单测。

* feat(macos): 新增插件工作区文件访问的宿主内部服务(API-06/07/08)

尚未暴露为插件公共 API,也未改动 shared/contracts、capabilities.rs 和 hostCapabilities;
M0 分发层负责授权并把插件请求映射为显式根和调用方身份。

- Core/Ports/PluginWorkspaceFileAccess.swift:服务协议与值类型。每次调用显式携带
  工作区根(root ID、目录、authority、generation、可见性规则)和调用方身份,不回退到活动窗口;
  资源 ID 为 root ID + 以 / 分隔的 NFC 相对路径,结果中不出现系统绝对路径;
  错误分类、集中的预算常量及每个取值的依据。
- MacWorkspaceSecurePath:路径词法校验(拒绝绝对路径、空段、.、..、NUL、超长段和超长路径),
  逐段 NFC 规范化;从根描述符逐段 openat(O_NOFOLLOW) 解析,末段用 fstatat(AT_SYMLINK_NOFOLLOW)
  或 O_NOFOLLOW|O_NONBLOCK 打开,防止 .. 越界、任意段的符号链接以及检查后换成链接的 TOCTOU;
  注释写明能防和不能防的范围(硬链接、持有描述符期间被移出的目录、挂载点)。
- MacPluginWorkspaceFileService:
  - readDirectory 用不透明游标分页(游标绑定根、generation 和目录,记录最后一个排序键),
    单页上限和单目录扫描上限;排序与项目树一致(目录优先、自然文件名序),
    隐藏规则、符号链接和嵌套 linked worktree 的省略也与项目树一致。
  - stat 报告链接本身。readFile 有字节上限、编辑器同款编码探测、二进制结果、截断标记,
    未截断时附带 SHA-256 身份。
  - findFiles/findText 复用现有搜索 owner(Search Everywhere 文件提供者和项目文本搜索),
    支持取消、偏移游标分页和截断标记,结果标明只来自磁盘、不含未保存缓冲区。
  - 拒绝非本地 authority,以及被标为本地的远程占位根(unsupportedAuthority);
    旧的或已关闭的 generation 返回 staleWorkspace。
  - 阻塞工作在宿主队列上执行;按调用方限制并发;任务取消时立即返回 cancelled。
- MacPluginWorkspaceWatchHub:复用 DirectoryWatcherFactory/DirectoryChangeSource,
  同一根 generation 的订阅共享一个变更源并做引用计数;订阅归属调用方和工作区,
  在 dispose、releaseResources、closeWorkspace 或新 generation 取代时释放;
  高频事件按订阅合并,超出待处理上限或源报告丢失时折叠为“需要重新扫描”;
  旧 generation 的迟到事件按键丢弃,不会到达新订阅;dispose 返回后不再投递。
- MacWorkspaceSnapshotBuilder.isNestedLinkedWorktree 改为 internal 以复用。
- PluginWorkspaceFileServiceTests 覆盖:越界与路径校验、根外符号链接、
  链接互换竞态(含中途换链接)、分页游标与篡改、超大目录、隐藏规则、二进制文件、
  超限截断、NFC 名称、watcher 释放/合并/溢出/旧 generation、远程 authority 拒绝、
  搜索分页与不可用、取消与并发预算。

* feat(macos): 增加插件宿主的编辑器打开、HTML 预览、外部浏览器和窗口消息内部服务

实现 docs/development/macos-plugin-api-plan.md 中 API-15、API-16 和 API-17
最小部分的宿主内部服务。只提供 Swift 协议和实现,不对插件公开,不修改插件契约、
Rust capabilities 和 PluginTypes 的 hostCapabilities,授权与调用分发留给 M0。

作用域与资源
- 每次调用显式携带插件、窗口、工作区和工作区代际,不回退到当前活动窗口。
- PluginHostScopeGate 在窗口缺失、远程工作区、工作区或代际变化时拒绝,并在每个
  等待点之后再次校验,窗口关闭或工作区替换后不再放光标、不再启动浏览器。
- 资源使用“根 ID + 工作区相对路径”,在符号链接解析后按带尾部斜杠的前缀比较,
  拒绝路径逃逸、兄弟目录前缀、控制字符和超长路径。

editor.open / reveal
- 复用 documentFeature.openFileAsync 和文档 owner:已打开的文档只激活不重载,
  未保存缓冲区保持原样;没打开才从磁盘加载一次。
- activation 为 select 时调用 selectEditorTab,等同点击标签,把后台标签切成前台
  标签,编辑器切片读选区、改文本前需先走这条路径;background 不改前台标签、
  不放光标。结果中 isActive 表示标签在前台,windowIsForeground 表示窗口在前台。
- 后台窗口只在自己的窗口内工作,不提升窗口、不激活应用。
- range 只落到起点光标并在结果里明示;可替换预览标签暂不支持,明确拒绝。
- reveal 要求文件已打开,否则返回 documentNotOpen。

preview.openHTML
- 仅接受 .html/.htm,走 editor.open 的 select 路径,内嵌预览使用当前缓冲区。
- 仅预览模式是标签视图的 @State,暂不支持,明确拒绝。

browser.openExternal
- 网址只允许 http/https,必须有主机名,禁止用户信息、空白和控制字符,限长
  4096 字节;其它 scheme 一律拒绝,不追加内容、不执行脚本。
- 本地文件只接工作区内的 .html/.htm,让系统浏览器读磁盘;打开前先让编辑器交出
  未报告的输入,缓冲区脏或编辑器未确认都按“有未保存修改”处理。调用方可选择
  openSavedFile 并在结果里明示,或 requireSaved 返回 unsavedChanges。
- PlatformUI 新增 openWebURLInBrowser;MacHTMLBrowserOpener 新增 openWeb,
  自身再次校验协议和主机,只向 Launch Services 查询处理浏览器。

window.showInformation / Warning / Error
- 每个窗口一个 PluginHostMessageFeatureModel,WorkbenchView 左下角用
  PluginHostMessageStack 原样显示插件文字和按钮,不走会翻译文案的宿主通知栈。
- 最多同时显示 3 条,其余排队;返回用户选择的按钮序号或关闭、窗口关闭、
  工作区替换、调用取消等结束原因,每条消息恰好结束一次。
- 限额:同一插件每窗口 10 秒 5 条、同时 3 条,每窗口共 10 条;文字 2000 字符,
  按钮 3 个、每个 40 字符。超频返回 rateLimited 并向用户提示一次,队列满返回
  messageQueueFull;限频时间由调用方注入。
- 宿主自己的 20 条文案补齐 shared/i18n 中英词条并重新生成。

HTML 预览与 plugin bridge 隔离
- 核对结论:预览使用全新的 WKWebViewConfiguration,唯一脚本处理器是应用内容世界里
  的 litheScrollbarFrame;lithe 消息处理器和 lithe-plugin 协议只在
  MacPluginWebPage,项目页面和外部浏览器都拿不到 bridge,无需改代码。
- 新增 HTMLPreviewBridgeIsolationTests 作为回归测试。

测试与文档
- 新增 PluginHostEditorServiceTests、PluginHostBrowserServiceTests、
  PluginHostMessageServiceTests(含限频器与编辑器同步等待)、
  HTMLPreviewBridgeIsolationTests,并扩展 HTMLBrowserOpenerTests;测试使用假窗口、
  注入时钟和有界等待,不依赖 sleep。
- 新增 Agent Note 2026-10-30-plugin-host-open-preview-services.md,记录决策、
  前台标签与前台窗口的区别、未保存语义、bridge 隔离证据、运行期不写发行包、
  已知限制和被否方案。

本次未在本机编译或运行 Swift 测试。

* fix(macos): isolate editor flush request to the main actor

* feat(plugins): give each host error its own JSON-RPC code from protocol 3

Record the backend workspace context and host services in the platform
feature matrix, and require one-to-one error codes in develop-lithe.

* fix(macos): make the editor flush callback sendable

* feat(core): add host notifications, failure details and finer host error codes

* feat(macos): push host notifications to plugin backends and tighten workspace contexts

- Push lithe/host/workspace/didChangeContexts to running backends granted
  workspace on every context open, change, or close.
- Deliver lithe/host/commands/didRun to a backend 2 plugin when its command
  runs: at once when ready, after the start when starting, and only on its
  own onCommand:<id> when stopped.
- Send subscription events with a per-subscription sequence through
  lithe/host/subscriptions/notify; notifications to one backend stay in
  order and are cancelled with the session.
- Start onWorkspaceOpen backends on enable or register when a workspace is
  already open.
- Grant a backend only the host services this host has handlers for, so
  getCapabilities lists nothing that fails for want of one.
- Switching a window to another workspace closes its context and opens one
  with a new contextID; generation counts changes of the same workspace.
- Make rootID an HMAC keyed per plugin with a host secret kept in
  Application Support/Lithe/PluginHost/root-id.key (0600, created once).
- listContexts no longer returns or creates stateDirectory; getContext does.
- Add notFound, readOnly, unsupportedOption, preconditionFailed, busy and
  rateLimited host error codes and structured failure details.
- Fix the dispose error message, document the protocol 3 notifications,
  details, error-code range, and context semantics in the contract, the
  Rust Core API, the Agent Note, and the feature matrix.

* feat(plugins): extend protocol 3 additively instead of new versions

- From protocol 3, new host services, methods, notifications, options,
  result fields and failure codes are added within the version and found
  with getCapabilities; only a change an existing backend would misread
  needs a new protocol version.
- Core answers a field a host method does not define with
  plugin.host.unsupportedOption (-32018) and details { option } for a
  version 3 session, before the host sees the request; version 2 keeps
  plugin.host.invalidParams.
- Document the extension rule and the backend's duties (call only listed
  methods, ignore unknown fields and notifications, treat unknown numbers
  as host failures) in the contract README, the outcomes table, the Agent
  Notes, and the feature matrix; add fixture and engine tests.

* feat(plugins): connect public host APIs and harden backend lifecycle

* fix(plugins): preserve older backends when host notifications are unsupported

* test(macos): stabilize Agent popup clicks and record API-01–44 completion

- Agent selector/activity tests: fix the hosting view size only where the
  layout needs it, display windows before synthesized clicks, and compute
  click points from LitheDropdownMetrics in flipped and unflipped documents.
- macOS plugin API plan: add the per-API completion table for PR #1595 and
  a summary of the public host methods with their permissions.
1lck added a commit that referenced this pull request Oct 30, 2026
* perf(lsp): stop copying open documents and draining events on the main actor

The engine copied the whole client state for every request, document
change, and server message while holding the session locks. That state
holds the full text of every open document, so a jdtls project import,
which publishes thousands of messages, kept completion and navigation
waiting behind the copies. Open document text is now shared (Arc<str>,
still a plain JSON string), and each server message is parsed once,
outside the state lock, instead of up to three times.

macOS drained Core's event queue on the main actor every 10 ms while
requests were pending, waiting on the same session lock. The drain now
runs off the main actor; a send waits for a drain already in flight, so
a drain still never returns a reply before its operation is registered.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* perf(jdt): key the workspace on build structure and tune the jdtls JVM

The JDT -data fingerprint no longer includes build-file mtime or size.
jdtls already detects pom and Gradle script edits itself
(MavenProjectImporter.needsMavenUpdate, GradleProjectImporter.
checkGradlePersistence), so switching to a fresh -data directory on every
edit only turned an incremental update into a full re-import. The Gradle
wrapper distribution stays part of the key because jdtls does not check it.

jdtls now launches with the GC and logging defaults vscode-java and the
upstream CI use (ParallelGC with GCTimeRatio=4 and
AdaptiveSizePolicyWeight=90, -Xlog:disable, DetectVMInstallationsJob
disabled). A plugin option with the same key replaces each default, and a
plugin collector choice replaces ParallelGC.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs(matrix): record the JDT workspace key and jdtls JVM defaults

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* refactor(run): keep detected run configurations in memory, not in the workspace

Identifying a project wrote .lithe/run/generated.json, toolchains/
requirements.json, project.json and .gitignore into the user's workspace, and
Run and Debug stayed unavailable until the user pressed "Identify project".

Core now owns the detected layer:
- runConfig.generate stores its result per workspace in process memory
  (execution/generated_layer.rs); inspect, resolve, user-configuration id
  checks and toolchain diagnostics read it from there.
- An optional cacheDirectory records the result in the application cache so a
  new session can list JDT's previous Java entry points before JDT answers.
  A .lithe/run/generated.json left by older versions is only read as that
  seed, never written.
- resolve picks the default configuration (framework service first, else the
  first detected entry other than Current File) when project.json names none.
- selectJava derives the project JDK minimum from pom.xml / .java-version /
  the Maven wrapper before any generation.

Hosts stop writing detection files and identify automatically:
- Windows removes run_write_generated; the run store identifies a project on
  load when inspect reports missing, without the entry-count notice.
- macOS removes MacRunConfigurationStore.writeGenerated, passes the cache
  directory, identifies after the workspace snapshot is applied, and drops the
  "regenerate broken generated.json" action.
- UI copy no longer mentions generated.json (shared i18n regenerated).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(run): restore detected entries alongside saved tasks after restart

* Merge pull request #1568 from 1lck/codex/macos-global-style

feat(macos): 补齐全局编辑器样式与 VS Code/IDEA 语法配色

* Merge pull request #1567 from 1lck/codex/issue-1564-global-search

fix(search): 修复搜索布局并支持文件名优先展示与滚动自动分页

* feat(editor): 类方法跳转默认开启并新增 Java 关键字跳过查询设置 (#1561)

* feat(macos):完善类方法跳转与悬停导航交互

* fix(macos): 稳定慢查询期间的 Command 悬停光标

* fix(editor): present Java files after initial import folding

* fix(editor): delay Command hover hints and cancel pending hints on leave

* fix(editor): show Command navigation feedback before semantic lookup

* fix(editor): exclude non-code tokens from Command navigation

* fix(editor): color Java comment delimiters as comments

* feat(macos): preserve navigation toggle implementation for integration

* fix(macos): unify welcome actions and clone remote panels

* feat(java-support): own optional class and method navigation lifecycle

* fix(navigation): sync plugin opt-out across projects and preserve other providers

* fix(i18n): preserve catalog ordering after preview merge

* test: align Java generator host capabilities and pin Git fixture branch

* fix(remote): resolve daemon startup before attaching concurrent clients

* fix(windows): provide the optional Java requirements snapshot

* feat(editor): 类方法跳转默认开启并新增 Java 关键字跳过查询设置

- 撤销插件级 classMethodNavigation / editorNavigation 开关(设置、策略表、校验和契约 fixture)。F12、Command 点击、悬停提示和 implementation 回退对所有语言默认生效,由宿主统一实现。
- 新增宿主设置“Java 关键字不查询定义”(设置 → 编辑器,默认开启):关键字位置不再发送定义查询,避免语言服务器对 static、switch 等关键字等待约 7 秒。
- Java 库类跳转优先读取本地 -sources.jar(~/.m2、~/.gradle 缓存),找不到时回退到 JDT LS 反编译。
- 删除已废弃的开关截图,新增关键字设置截图。

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>

* fix(matrix): 移除已删除的 editor-navigation fixture 证据路径

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>

* fix(navigation): 仅对 jar 内库类异步查找 sources jar

非 jar 的虚拟文档保持同步请求语言服务器,避免选择器接受目标后的源码请求被推迟;
合并 preview 并修复 Java 实现选择器相关回归测试。

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>

* fix(navigation): 撤回 sources jar 快速路径并保留 this/super 构造器跳转

- 撤回本地 sources jar 快速路径:文本与 JDT 返回的坐标不一定对应,且 jar 文件名无法确认依赖身份,统一回到语言服务器虚拟文档。
- Java 关键字过滤不再包含 this 和 super,它们对应构造器调用,仍会发送定义查询。

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>

* test(macos): align rollback symlink assertion with document errors

* test(git): 为子模块测试的 git submodule add 放宽超时

Windows runner 上 git submodule add 克隆子模块超过辅助函数写死的 10 秒,
进程被取消,导致 watch_context_resolves_a_submodule_git_directory_outside_its_workspace
失败。该测试的时间预算已在 test-stability-windows.ps1 中放宽到 30 秒,
这里把命令超时与预算保持一致,其余 git 命令仍使用 10 秒。

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Haiku 5.5 <noreply@anthropic.com>
Co-authored-by: lick <2188718831@qq.com>

* fix(run): 只将已确认的 Java 应用识别为 Spring 服务 (#1593)

* fix(run): require confirmed Java entries for Spring services

* docs(run): align launch boundary with confirmed Spring entries

* test(run): require confirmed services in persistence fixtures

* fix: 连续输入时刷新两端 LSP 补全候选 (#1592)

* fix(lsp): preserve completion refresh context across editor hosts

* fix(completion): type trigger mapping and adapter expectations

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>

* 统一 Java 启动准备并补齐保存到构建的同步 (#1594)

* Unify Java launch preparation and notify language servers after saves

* fix(windows): refresh buffers before launch save notifications

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>

* fix(windows): 启动反馈、Blame 闪烁、导入进度与全局 Maven 设置 (#1600)

* fix(windows): startup feedback, blame flicker, import progress and global Maven settings

- Agent host subprocesses (environment probe, subscription quota, MCP probe)
  start with CREATE_NO_WINDOW so the Agent panel no longer flashes consoles.
- Windows are created with the last applied theme background, stored in the
  app local data directory, instead of WebView2's white until first paint.
- Inline Git blame refreshes only for file or history changes, keeps the
  previous annotation while reloading, ignores index-only rewrites, and is
  off by default for new installs.
- The status bar shows Java import percentage, current module and download,
  then language-server background tasks; navigation during import reports
  the import progress and slow requests show a pending notice.
- The Maven settings page edits <localRepository> of the user's own
  ~/.m2/settings.xml without a project, with revision-checked writes.
- New "Import Java projects on open" setting: automatic, ask or manual.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(windows): honour the import policy in run discovery and translate Maven settings errors

- Automatic run-configuration generation on project load no longer starts
  the Java import when the user chose to be asked or to import manually; an
  explicit generate still starts it.
- The Maven user-settings host returns error codes that the settings page
  maps to translated messages; OS errors are shown inside a translated frame.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(windows): drive the Maven user settings draft through the injected picker

Typing relied on React's input-event plugin seeing this file's DOM, which
fails when another test file loaded react-dom first in the same process.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(windows): serialize window background writes and keep linked settings.xml

- Windows applying a theme at the same moment shared one temporary file;
  writes now take turns under a process-wide lock.
- Saving the user Maven settings writes through a symlinked settings.xml
  instead of replacing the link with a regular file.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(windows): keep the shared navigation notice until the last slow request settles

Each navigation dismissed the shared "Finding…" notice when it finished,
hiding it while an earlier slow request still waited. The notice now counts
the requests showing it and closes after the last one.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(windows): drop background tasks when a language server process restarts

A recovered process never ends the previous process's work, so its tasks
would stay in the status bar.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>

* feat(macos): 补齐提交文件操作、批量回滚确认与初始布局 (#1591)

* feat(macos): complete commit file actions and rollback confirmation

* fix(git): publish file mutations before workspace recovery

* fix(macos): refresh open commit panels independently of project reloads

* test(macos): drive native rendering while awaiting LSP snapshot updates

* fix(macos): 目录删除前避开 Provider 歧义根并重新发现仓库根

- Git 未跟踪目录删除的资格检查纳入 Provider 的歧义根,嵌套但未选定 VCS 的工作副本不再随父目录移入废纸篓
- Git 与插件的未版本化目录废纸篓删除在执行前有界地重新发现 Provider 根;结果与缓存不一致、被截断或失败时拒绝并触发重新发现
- 补充歧义根与确认期间新增嵌套根的回归测试,更新提交文件操作 Agent Note

* feat(macos): 设置页新增网络代理,支持跟随系统/不走代理/自定义服务器 (#1571)

* feat(macos): 设置页新增网络代理,支持跟随系统/不走代理/自定义服务器

新增「外观与行为 › 网络」设置页,管理 Lithe 自身 HTTP 流量的代理策略:

- 三档模式:跟随系统(默认,即现状行为)、不走代理(显式禁用)、自定义代理服务器
- 自定义档完整字段:代理类型(HTTP/SOCKS5)、服务器地址、端口、
  可选用户名与密码(密码存 Keychain,经 SecureStore 端口读写,
  不入偏好存储)、逗号分隔的排除列表(kCFNetworkProxiesExceptionsList)
- 测试连接:经端口 NetworkProxyChecking 由 MacNetworkProxyTester 执行,
  HEAD github.com、10 秒有界超时,成功显示耗时或失败显示原因
- 统一接入点 MacNetworkSessionProvider:按 NetworkProxyPreferences
  快照缓存会话,配置变化时旧会话 finishTasksAndInvalidate;提供 applyPolicy
  供自带超时的稳定版回滚下载复用同一策略;自定义未填完整时按跟随系统处理
- 四个 URLSession 出口接入:插件市场传输与下载、GitHub 传输、AI HTTPS 传输、
  MacStableRollback;三个传输的 session 参数改为按请求解析的 sessionProvider,
  设置变化对新请求生效,无需重建服务
- 明确不接管并在设置页说明:Sparkle 更新(框架无会话注入 API,
  SPUDownloader 写死 defaultSessionConfiguration,天然跟随系统代理)、
  AI 明文 HTTP 的 NWConnection 分支、终端 git/Agent 子进程、JVM 依赖下载
- 新增 NetworkProxySettingsTests(16 例)与 MacNetworkSessionProviderTests;
  更新 SettingsSidebarLayoutTests;词条进 shared/i18n 真源并重新生成;
  功能矩阵新增 network-proxy-settings(macOS implemented/pending,
  Windows platform-specific)

* feat(macos): 网络代理自定义配置增加重置按钮

与保存成对:放弃未保存的草稿,把类型/地址/端口/用户名/排除列表
恢复为当前已保存生效的值;密码框不从 Keychain 回显,重置一并清空;
之前的测试连接结果随旧草稿一并清除。复用现有 native.reset 词条。

* chore(matrix): 网络代理设置 macOS 实机验收通过,转 verified

* refactor(network): 代理策略下沉 Rust 内核并修复评审缺陷

按维护者方向把双端可复用的代理逻辑下沉 Rust 内核,Swift 只保留
前端绑定与平台映射:

- 新增确定性命令 network.proxyPolicy(rust/lithe-core/src/network/):
  归一化(trim、排除列表清洗、密码保形)+ 校验(未填完整的 custom
  归一为 system),共享 fixture proxy-policy-v1.json 预钉跨平台契约,
  契约文档补索引与 Network proxy 小节
- Swift 侧新增 RustCoreBridge+NetworkProxy 桥接;MacNetworkSessionProvider
  改持 policyResolver(组合根注入桥接,测试注入静态计划),CFNetwork
  字典映射保留为平台专属部分,以 Rust 返回的 plan 为唯一事实来源

修复评审 4 项缺陷:
- P1 初始化同步:updateNetworkProxyPreferences 移到 init 真正末尾
  (原先误落在 restoreDefaults),重启后快照恢复已存策略;补重建设置
  对象后检查快照的回归测试
- P1 凭据隔离:凭据仅绑定到其所属代理(质询主机/端口需与配置一致),
  系统/直连会话不挂凭据 delegate,杜绝凭据发给其他系统代理
- P2 测试连接使用有效密码:草稿为空时回退已保存密码
- P2 Keychain 写失败保留密码草稿与重试入口

复用现有 native.reset 词条的重置按钮行为不变;Swift 侧归一化去重,
归 Rust 权威。

* fix(network): 隔离代理凭据并修复会话与连接测试生命周期

将密码与代理身份同存 Keychain,由 Rust 归一化策略拒绝跨端点复用;旧版无身份密码需重新输入。以覆盖响应消费的会话租约避免设置切换时提前失效,并让稳定版回滚复用完整认证会话工厂。连接测试增加资源总超时、取消和过期结果隔离。补共享 fixture、回归测试、中英提示与决策笔记。验证:Swift 85 项、Rust 1373 单元及 32 集成测试、i18n 35 项及相关静态门禁通过;真实代理产品验收保持 pending。

---------

Co-authored-by: Yao Jingxi <23722032@bjtu.edu.cn>

* feat(icons): add common project file glyphs and bot Agent icon (#1606)

- macOS/Windows: dedicated icons for .gitignore/.gitattributes, go.mod/go.sum,
  Makefile, package.json, lock files, README and LICENSE (#1584)
- Windows icon generator accepts lithe: sources for original icons; PowerShell
  icon moves under it so regeneration keeps it
- Agent tool-window entry uses the Lucide bot glyph on both platforms

* feat(plugins): macOS 公共宿主 API、纯命令与后端生命周期补全 (#1595)

* docs(plugins): 按 preview e8c4e9f 刷新 macOS 插件 API 计划

#1517(原生 Provider 工作流)和 #1515(远程工作区适配)都已合并,
计划里"在途/未合并"的说法已过时。本次只改文档,不改运行时代码、
schema、SDK 和功能矩阵状态。

基线与现状
- 盘点基线:Lithe 更新为 preview e8c4e9f;#1517 记为已合并;新增 #1515
  (阶段性实现,范围与缺口见 API-40);记录插件文档仓库 main 仍是
  be779d2000e3,且其契约锁落后主仓库 4 个触及 plugins/v1 的提交
- 能力版本:对照 PluginTypes.swift 与 capabilities.rs,补上
  buildProviders 1–6、buildModelInputs 1、debugAdapters 1/2;
  Core 与 Mac 唯一差异是 serverProcess(Core 1/2,Mac 1)
- API-29、API-31、API-35、M4、DOC-12、5.1 SDK 行:去掉对 #1517 在途的依赖,
  改为已合并后的文档、SDK 对齐与端到端验收

新增条目(编号接续 API-39,不改动既有编号)
- API-40 工作区 authority(M0):远程工作区仍是本机空占位根,backend:1 与
  Web bridge 不识别远程绑定;未实现的 authority 必须明确拒绝。API-05、
  API-35 同步指向它
- API-41 激活事件与启动预算(M0/M1):现有 activationEvents 只与已声明的
  Provider/窗口命令一一对应;应用没有工作区信任概念,M0 需决定
- API-42 内置 Git 只读快照(M3):Git 不在统一 VCS 层,API-31 只覆盖插件 VCS
- API-43 documents.onWillSave(M3):保存路径没有保存前钩子
- API-44 Agent 侧贡献(后续):Skills/Hooks/MCP 是用户管理的原生配置,
  没有插件来源
- 同步 2.1 现状表、4.1/4.2 评审清单、阶段表 M0/M1/M3c/M4/后续、
  DOC-02/04/07/13 以及新增 DOC-18/19、来源索引 S20–S22

公共扩展契约提案(proposed Note)
- 修正"内置 Git 与插件 VCS 共用同一统一模型",与 2026-10-22 评审一致:
  Git 暂不接入统一层
- #1517 改为已合并,补 #1515 的范围;新增 authority/激活/保存前事件/
  Agent 侧贡献一节,说明本 Note 不预设答案

* 插件后端 2 与函数协议 3:工作区上下文、能力发现与宿主错误码

- requires.backend 新增版本 2:可由 onWorkspaceOpen 或插件命令启动,不再必须有网页;后端可以是插件唯一内容;backend 1 语义不变
- 新权限 workspace.metadata(仅 backend 2)授予 workspace 宿主服务;拒绝 onStartupFinished 等常驻启动事件
- 插件函数协议新增版本 3:lithe/host/getCapabilities 由 Core 直接回答,subscriptions/dispose,workspace/listContexts、getContext、getFolders
- 宿主方法改为表驱动(HOST_METHODS),后续文件、编辑器、窗口服务按行接入
- lsp.functionRequest 可携带 context,仅 v3 后端收到 params.context
- lsp.hostResponse.error 可带 code,按白名单映射为 contextExpired、authorityUnsupported、versionConflict、limitExceeded、cancelled、timeout 等
- 后端可用 $/cancelRequest 取消自己的宿主请求,Core 立即回复 cancelled 并发出 hostRequestCancelled 事件
- 同步契约 README、manifest schema、正反例 fixture 与 Rust 单元测试

* feat(macos): 插件后端 backend 2 的工作区上下文、激活事件与宿主服务分发

- hostCapabilities 提供 backend [1, 2]
- 新增 PluginWorkspaceContexts:每窗口一个上下文,contextID 加 generation,本地/远程 authority,rootID 与状态目录摘要
- 新增 PluginHostServiceDispatcher 与 PluginHostServiceHandling 扩展点,统一错误码、授权与上下文核验、订阅回收与宿主请求取消;凭据与 workspace 服务接入
- MacPluginBackendSessions 支持 onWorkspaceOpen 与 onCommand 激活(串行、不阻塞),调用携带工作区上下文
- RustCoreBridge 传递 lsp.functionRequest.context 与 hostResponse.error.code,会话处理 hostRequestCancelled
- 新增界面文案词条并重新生成;新增 Agent Note 记录设计、第 4 节回答与威胁模型,写明工作区信任暂不引入

* test(macos): 补上上下文测试缺少的 throws 声明

* feat(macos): 为插件 API-09/10 提供宿主内部文档与编辑器服务

实现 macos-plugin-api-plan 中 API-09(documents.list/getSnapshot、
editor.getActive/getSelections)和 API-10(editor.applyEdits/
replaceSelections/insertText)的 Mac 宿主内部服务,暂不对插件公开,
等 M0 分发层接入。

- EditorDocumentService:调用方必须显式传入窗口与工作区范围和文档 ID,
  不回退到当前活动窗口;读取的是含未保存修改的内存缓冲区。
- 新增 EditorDocument.contentVersion 作为版本来源:每次文本变化单调
  递增,不受保存/冲突决策改写,没有 WebView 时也存在,WebView 重载
  后不归零。
- 坐标:行、列都从 1 开始,列按 UTF-16 码元计数;CR/LF/CRLF 各算
  一次换行。只在 LSP 适配边界换算成从 0 开始。
- EditorTextEditPlanner 先校验整批编辑(越界、反向、拆开代理对、
  重叠),全部通过才下发;插入的换行沿用文档首个换行符。
- Monaco 适配:同步比对桥接 revision;JS 端再核对 revision 和未确认
  输入,有 IME 组字、只读、冻结或关闭中时拒绝;用前后两个 undo stop
  加 pushEditOperations 作为一个撤销步骤应用;编辑消息带 origin,
  用来回报这一批产生的精确版本。
- SourceText.apply 支持按批次指定 EOL。
- 补充 Swift 单测(emoji、组合字符、CRLF、中文、多选区、版本冲突、
  只读、越界、重叠)和 bun 单测。

* feat(macos): 新增插件工作区文件访问的宿主内部服务(API-06/07/08)

尚未暴露为插件公共 API,也未改动 shared/contracts、capabilities.rs 和 hostCapabilities;
M0 分发层负责授权并把插件请求映射为显式根和调用方身份。

- Core/Ports/PluginWorkspaceFileAccess.swift:服务协议与值类型。每次调用显式携带
  工作区根(root ID、目录、authority、generation、可见性规则)和调用方身份,不回退到活动窗口;
  资源 ID 为 root ID + 以 / 分隔的 NFC 相对路径,结果中不出现系统绝对路径;
  错误分类、集中的预算常量及每个取值的依据。
- MacWorkspaceSecurePath:路径词法校验(拒绝绝对路径、空段、.、..、NUL、超长段和超长路径),
  逐段 NFC 规范化;从根描述符逐段 openat(O_NOFOLLOW) 解析,末段用 fstatat(AT_SYMLINK_NOFOLLOW)
  或 O_NOFOLLOW|O_NONBLOCK 打开,防止 .. 越界、任意段的符号链接以及检查后换成链接的 TOCTOU;
  注释写明能防和不能防的范围(硬链接、持有描述符期间被移出的目录、挂载点)。
- MacPluginWorkspaceFileService:
  - readDirectory 用不透明游标分页(游标绑定根、generation 和目录,记录最后一个排序键),
    单页上限和单目录扫描上限;排序与项目树一致(目录优先、自然文件名序),
    隐藏规则、符号链接和嵌套 linked worktree 的省略也与项目树一致。
  - stat 报告链接本身。readFile 有字节上限、编辑器同款编码探测、二进制结果、截断标记,
    未截断时附带 SHA-256 身份。
  - findFiles/findText 复用现有搜索 owner(Search Everywhere 文件提供者和项目文本搜索),
    支持取消、偏移游标分页和截断标记,结果标明只来自磁盘、不含未保存缓冲区。
  - 拒绝非本地 authority,以及被标为本地的远程占位根(unsupportedAuthority);
    旧的或已关闭的 generation 返回 staleWorkspace。
  - 阻塞工作在宿主队列上执行;按调用方限制并发;任务取消时立即返回 cancelled。
- MacPluginWorkspaceWatchHub:复用 DirectoryWatcherFactory/DirectoryChangeSource,
  同一根 generation 的订阅共享一个变更源并做引用计数;订阅归属调用方和工作区,
  在 dispose、releaseResources、closeWorkspace 或新 generation 取代时释放;
  高频事件按订阅合并,超出待处理上限或源报告丢失时折叠为“需要重新扫描”;
  旧 generation 的迟到事件按键丢弃,不会到达新订阅;dispose 返回后不再投递。
- MacWorkspaceSnapshotBuilder.isNestedLinkedWorktree 改为 internal 以复用。
- PluginWorkspaceFileServiceTests 覆盖:越界与路径校验、根外符号链接、
  链接互换竞态(含中途换链接)、分页游标与篡改、超大目录、隐藏规则、二进制文件、
  超限截断、NFC 名称、watcher 释放/合并/溢出/旧 generation、远程 authority 拒绝、
  搜索分页与不可用、取消与并发预算。

* feat(macos): 增加插件宿主的编辑器打开、HTML 预览、外部浏览器和窗口消息内部服务

实现 docs/development/macos-plugin-api-plan.md 中 API-15、API-16 和 API-17
最小部分的宿主内部服务。只提供 Swift 协议和实现,不对插件公开,不修改插件契约、
Rust capabilities 和 PluginTypes 的 hostCapabilities,授权与调用分发留给 M0。

作用域与资源
- 每次调用显式携带插件、窗口、工作区和工作区代际,不回退到当前活动窗口。
- PluginHostScopeGate 在窗口缺失、远程工作区、工作区或代际变化时拒绝,并在每个
  等待点之后再次校验,窗口关闭或工作区替换后不再放光标、不再启动浏览器。
- 资源使用“根 ID + 工作区相对路径”,在符号链接解析后按带尾部斜杠的前缀比较,
  拒绝路径逃逸、兄弟目录前缀、控制字符和超长路径。

editor.open / reveal
- 复用 documentFeature.openFileAsync 和文档 owner:已打开的文档只激活不重载,
  未保存缓冲区保持原样;没打开才从磁盘加载一次。
- activation 为 select 时调用 selectEditorTab,等同点击标签,把后台标签切成前台
  标签,编辑器切片读选区、改文本前需先走这条路径;background 不改前台标签、
  不放光标。结果中 isActive 表示标签在前台,windowIsForeground 表示窗口在前台。
- 后台窗口只在自己的窗口内工作,不提升窗口、不激活应用。
- range 只落到起点光标并在结果里明示;可替换预览标签暂不支持,明确拒绝。
- reveal 要求文件已打开,否则返回 documentNotOpen。

preview.openHTML
- 仅接受 .html/.htm,走 editor.open 的 select 路径,内嵌预览使用当前缓冲区。
- 仅预览模式是标签视图的 @State,暂不支持,明确拒绝。

browser.openExternal
- 网址只允许 http/https,必须有主机名,禁止用户信息、空白和控制字符,限长
  4096 字节;其它 scheme 一律拒绝,不追加内容、不执行脚本。
- 本地文件只接工作区内的 .html/.htm,让系统浏览器读磁盘;打开前先让编辑器交出
  未报告的输入,缓冲区脏或编辑器未确认都按“有未保存修改”处理。调用方可选择
  openSavedFile 并在结果里明示,或 requireSaved 返回 unsavedChanges。
- PlatformUI 新增 openWebURLInBrowser;MacHTMLBrowserOpener 新增 openWeb,
  自身再次校验协议和主机,只向 Launch Services 查询处理浏览器。

window.showInformation / Warning / Error
- 每个窗口一个 PluginHostMessageFeatureModel,WorkbenchView 左下角用
  PluginHostMessageStack 原样显示插件文字和按钮,不走会翻译文案的宿主通知栈。
- 最多同时显示 3 条,其余排队;返回用户选择的按钮序号或关闭、窗口关闭、
  工作区替换、调用取消等结束原因,每条消息恰好结束一次。
- 限额:同一插件每窗口 10 秒 5 条、同时 3 条,每窗口共 10 条;文字 2000 字符,
  按钮 3 个、每个 40 字符。超频返回 rateLimited 并向用户提示一次,队列满返回
  messageQueueFull;限频时间由调用方注入。
- 宿主自己的 20 条文案补齐 shared/i18n 中英词条并重新生成。

HTML 预览与 plugin bridge 隔离
- 核对结论:预览使用全新的 WKWebViewConfiguration,唯一脚本处理器是应用内容世界里
  的 litheScrollbarFrame;lithe 消息处理器和 lithe-plugin 协议只在
  MacPluginWebPage,项目页面和外部浏览器都拿不到 bridge,无需改代码。
- 新增 HTMLPreviewBridgeIsolationTests 作为回归测试。

测试与文档
- 新增 PluginHostEditorServiceTests、PluginHostBrowserServiceTests、
  PluginHostMessageServiceTests(含限频器与编辑器同步等待)、
  HTMLPreviewBridgeIsolationTests,并扩展 HTMLBrowserOpenerTests;测试使用假窗口、
  注入时钟和有界等待,不依赖 sleep。
- 新增 Agent Note 2026-10-30-plugin-host-open-preview-services.md,记录决策、
  前台标签与前台窗口的区别、未保存语义、bridge 隔离证据、运行期不写发行包、
  已知限制和被否方案。

本次未在本机编译或运行 Swift 测试。

* fix(macos): isolate editor flush request to the main actor

* feat(plugins): give each host error its own JSON-RPC code from protocol 3

Record the backend workspace context and host services in the platform
feature matrix, and require one-to-one error codes in develop-lithe.

* fix(macos): make the editor flush callback sendable

* feat(core): add host notifications, failure details and finer host error codes

* feat(macos): push host notifications to plugin backends and tighten workspace contexts

- Push lithe/host/workspace/didChangeContexts to running backends granted
  workspace on every context open, change, or close.
- Deliver lithe/host/commands/didRun to a backend 2 plugin when its command
  runs: at once when ready, after the start when starting, and only on its
  own onCommand:<id> when stopped.
- Send subscription events with a per-subscription sequence through
  lithe/host/subscriptions/notify; notifications to one backend stay in
  order and are cancelled with the session.
- Start onWorkspaceOpen backends on enable or register when a workspace is
  already open.
- Grant a backend only the host services this host has handlers for, so
  getCapabilities lists nothing that fails for want of one.
- Switching a window to another workspace closes its context and opens one
  with a new contextID; generation counts changes of the same workspace.
- Make rootID an HMAC keyed per plugin with a host secret kept in
  Application Support/Lithe/PluginHost/root-id.key (0600, created once).
- listContexts no longer returns or creates stateDirectory; getContext does.
- Add notFound, readOnly, unsupportedOption, preconditionFailed, busy and
  rateLimited host error codes and structured failure details.
- Fix the dispose error message, document the protocol 3 notifications,
  details, error-code range, and context semantics in the contract, the
  Rust Core API, the Agent Note, and the feature matrix.

* feat(plugins): extend protocol 3 additively instead of new versions

- From protocol 3, new host services, methods, notifications, options,
  result fields and failure codes are added within the version and found
  with getCapabilities; only a change an existing backend would misread
  needs a new protocol version.
- Core answers a field a host method does not define with
  plugin.host.unsupportedOption (-32018) and details { option } for a
  version 3 session, before the host sees the request; version 2 keeps
  plugin.host.invalidParams.
- Document the extension rule and the backend's duties (call only listed
  methods, ignore unknown fields and notifications, treat unknown numbers
  as host failures) in the contract README, the outcomes table, the Agent
  Notes, and the feature matrix; add fixture and engine tests.

* feat(plugins): connect public host APIs and harden backend lifecycle

* fix(plugins): preserve older backends when host notifications are unsupported

* test(macos): stabilize Agent popup clicks and record API-01–44 completion

- Agent selector/activity tests: fix the hosting view size only where the
  layout needs it, display windows before synthesized clicks, and compute
  click points from LitheDropdownMetrics in flipped and unflipped documents.
- macOS plugin API plan: add the per-API completion table for PR #1595 and
  a summary of the public host methods with their permissions.

* fix(macos): restore settings window sessions after relaunch (#1599) (#1601)

* perf(windows): 修复文档漂移并大幅降低大文件打字成本 (#1605)

* fix(lsp): replay document changes in the order they happened

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* perf(editor): stop TextMate tokenizing once the rule state converges

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(windows): register the folder drop listener once

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* perf(windows): rebuild Spring and MyBatis indexes on the autosave pause

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* feat(windows): answer Java definitions from syntax while importing

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(windows): measure frontend interactions against budgets

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(windows): cover recoloring far below a multi-line edit

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(macos): cover CR positions through the source change path

sourcePositionAt no longer exists because positions now come from the
piece tree. Assert the same CR line counting on SourceText changes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(windows): start a fired autosave only once

The task stays queued until its write settles, so a blur during the claim
ran the same closure again. Both runs shared an operation id and could both
write, turning the second into a false conflict.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(java): resolve syntax member references from their scope

The whole-tree search returned the first same-named member, so a jump could
land in a nested type. A lookup now stays on the named type, and a reference
walks outward from where it is used, answering nothing when an inherited
name or a local could change the binding.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(windows): count the work typing leaves behind

Per-key metrics now share one window, and the final autosave and index
rebuild are reported separately once the host goes quiet. The new Windows
document sync, syntax navigation and perf statistics tests join CI.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>

* perf/fix(windows): 文件树交互与图标、文件菜单设置入口、Git 推送弹窗、工作区扫描提速 (#1586)

* fix(windows): 文件树单击仅选中、双击打开,并支持 Delete 键删除(始终二次确认)

- 单击文件只选中并高亮,不再打开或新建预览页签;双击或 Enter 才打开,与单击目录行为一致
- 选中后按 Delete 弹出删除确认框,多选时一次确认并逐项删除;
  即使“删除前确认”设置关闭也始终确认,工作区根目录与带修饰键的 Delete 不触发
- 补充选择与 Delete 键的组件测试,并更新跨平台功能矩阵说明

* fix(windows): Git Log 文件列表选中行跟随 Diff 预览的上一/下一文件导航

- Commit files 列表监听预览标签页当前显示的文件并同步选中行;
  仅当预览属于当前所选提交或范围时才同步,避免过期预览改变选中
- 同步选中时自动展开被折叠的父目录,并仅在纵向滚动到可见位置,不改变横向滚动
- 抽出 commitFilePreviewHash 与 selectedCommitFilePath,发布预览与观察预览共用同一标识
- 补充选中跟随与折叠目录自动展开的组件测试,并更新跨平台功能矩阵说明

* fix(windows): 推送弹窗按钮对齐 IDEA 样式并修复强制推送下拉被弹窗遮挡

- 推送按钮组改为 IDEA 默认选项按钮样式:实心主色底、白字,1px 分隔线上下内缩;
  ButtonGroup 新增 primary 变体,禁用时整组一起变淡
- 下拉箭头悬停和菜单展开时不变色;Button 带 tooltip 会被包一层 span,
  分组的直接子元素选择器无法命中,箭头改为自带样式
- DropdownMenu 定位层从 z-50 提到 z-10070,与 context-menu、popover、select 一致;
  此前弹窗(z-9999)会盖住强制推送菜单
- DropdownMenuContent 支持透传 anchor,强制推送菜单锚定整个按钮组,宽度与按钮组一致

* feat(windows): 文件菜单新增设置入口

针对 #1560 的第 1 点:点击左上角“文件”后,菜单里找不到设置入口。

- 文件菜单在“关闭标签页”上方新增“设置”项,齿轮图标加文字,上下以分隔线隔开,
  显示 Ctrl+, 快捷键提示;点击走已有的 menu_open_settings 事件,打开设置对话框
- 新增共享词条 menu.settings(设置 / Settings),重新生成 Windows i18n 资源
- 补充菜单源码断言测试:设置项位于“关闭标签页”和“退出”之前
- 新增功能矩阵条目 windows-file-menu-settings(Windows 已实现、待验证,macOS 不适用)

未覆盖:#1560 的第 2 点(菜单只有“退出”、没有“重启”)尚未实现,
因此只引用 issue,不关闭。

Refs #1560

* feat(file-tree): 补齐 Windows IDEA 图标主题并新增 jsonl/wbmp/Office/i18n 图标

- Windows IDEA Icons 主题补齐 macOS 已识别的类型:Kotlin、Rust、Go、Python、
  Ruby、Scala、PHP 图标(取自 IDEA,明暗各一份),以及 .m/.hh/.hxx/.mm/.fish/
  .svelte/.pom/.ini/.cfg/.conf/.env/.db/.sqlite/.markdown/.adoc/.tsv/.tiff/.icns、
  .class/.jar/.so/.dylib/.dll/.pdf 等扩展名,和 .classpath/.project/
  .gitattributes/.dockerignore/compose 文件等文件名
- .kts 改用 Kotlin 图标,.gradle.kts 仍用 Gradle 图标,与 macOS 一致
- 两端新增:.jsonl/.jsonlines/.ndjson/.ldjson 用 JSON 图标,.wbmp 用图片图标,
  .doc/.docx/.ppt/.pptx 用 IDEA Native 类型的 custom 图标,.strings 用 i18n 图标
- macOS LitheIconKind 新增 .i18n、.document,补充 custom/i18n 资源与 NOTICE 来源说明
- 新增 macOS FileTypeIconKindTests,并在 Windows 主题清单测试中覆盖新映射与资源
- 更新功能矩阵 file-explorer 的证据与验证说明

未覆盖:.env.*、dockerfile.* 这类前缀文件名在 Windows 主题里无法表达;
macOS 侧未在本机编译验证(当前环境为 Windows),验证状态保持 pending。

* perf(windows): 去掉项目文件树行的 hover 高亮

滚动时指针会连续扫过大量文件行,每行 hover 都会重绘整行覆盖的 ::before 伪元素,
造成滚动卡顿。

- file-explorer-tree.css 新增规则,在 .file-explorer-shell 内让行的 hover 背景保持透明;
  选中、焦点样式和缩进线不变
- Git 状态面板与提交文件树共用同一套样式,不在 .file-explorer-shell 内,hover 保持不变
- file-explorer-surface.test.ts 增加样式断言,防止该规则被误删

* perf(core): 工作区扫描默认跳过 Python 环境和字节码,Windows 快照只取文件清单

Python 项目里虚拟环境和 __pycache__ 占了绝大多数文件(一个典型项目约 3.2 万个文件中
约 2.7 万个),而打开项目时 Windows 会连续请求多次整库快照,每次都重复扫描并序列化
这些路径。

- Rust Core 内置隐藏名单增加 .venv、venv、__pycache__ 目录和 *.pyc 文件:这些目录整个
  不再被读取,也不进搜索索引、文件监听和 Git 仓库发现
- macOS FileVisibilityRules 同步增加同样四项,保持设置页显示的内置规则与实际规则一致
- Windows 的 fffListFiles 和 Lombok 导航请求 workspace.snapshot 时带 includeTree: false,
  不再让 Core 构造并序列化没人使用的整棵目录树(macOS 已在 #1245 这样做)
- 新增 Rust 测试覆盖快照、只要文件清单、目录列举和监听事件,并保留名字相近的目录可见;
  新增 Windows 测试断言快照请求只取文件清单
- 更新契约文档、lazy-project-tree 笔记,新增 Agent Note,补充功能矩阵 workspace-files

未覆盖:Windows 文件树仍按前端设置读磁盘目录,.venv 在 Windows 文件树里仍可见;
名字不同的虚拟环境不会被识别。macOS 侧未在本机编译验证(当前环境为 Windows),
验证状态保持 pending。

* fix(tests): 图标资源断言脱离应用 bundle,file-search 测试接入 Windows CI

- FileTypeIconKindTests 不再经 ideaImage 依赖 Bundle.main(单元测试宿主
  没有应用资源包,返回 nil 导致 Swift tests 失败):新增
  LitheIcons.ideaAssetPath(for:) 只读访问器解析目录映射,测试从源码
  Resources/IDEAIcons 断言明暗 SVG 存在,与 IDEAIconRasterizationTests
  的源码路径先例一致
- GitCommitTreeStyleTests 的 Localizable.strings 断言从 .plainText 更新
  为 .i18n,同步本 PR 的 .strings 图标映射变更
- ci-windows.yml 为 file-search-api.test.ts 新增独立计时步骤(该套件装
  进程级 Tauri 边界 mock,需与其他套件隔离执行);接入后暴露 mock 缺少
  isTauri/transformCallback 导出,按 tauri-core.test.ts 的 ...nativeCore
  展开模式修正

* fix(tests): 图标清单断言跟随 upstream #1606 新增的 AgentIcon

合并 upstream/preview 后,CI 的 "Test Agent panel and capability gate"
批次失败:application icon mappings > exports the complete icon inventory
断言 216 个图标导出,但 #1606 在 icons.tsx 新增了 AgentIcon(bot 图标),
导出数变为 217,且该 PR 合并时 CI 被取消未暴露此问题。

将断言更新为 217,本地完整重跑该批次 242 个测试全部通过。

* feat(windows): 行内 Git Blame 对齐 IDEA annotate(行号注释、Git Log 定位、右键菜单) (#1602)

* feat(windows): 行内 Git Blame 对齐 IDEA 行号注释

- 行号列渲染注释:作者与绝对日期浮在行号左侧,同一提交块只在首行显示,
  行号列随之加宽到 26ch 并在关闭后恢复
- 右键行号栏 Annotate with Git Blame / Hide Git Blame 按文件开关,
  删除全局 enableInlineGitBlame 设置(原行尾 widget 一并移除)
- 点注释用 openCommitDiffBuffer 打开该行提交的单文件 diff 并定位命中行
- 修正 core-result-adapter 的 total_lines:Core 每行一条记录,
  旧值让每条记录覆盖整文件,导致任意行显示别的提交
- 新增 git.blame.* 共享词条并移除旧设置词条

* fix(windows): Git Blame 注释按 IDEA 每行标注并右对齐

- 每行都显示作者与日期,不再按提交块合并(空行会被读成缺失归属)
- 标签右对齐紧贴行号,去掉贴最左 + 大段空隙的排版
- Annotate/Hide 入口只在行号区右键菜单出现,内容区菜单不再显示禁用项
- 图标改为作者语义的用户图标

* fix(windows): Git Blame 日期补零为 08/08/2026

月份与日期改为两位,避免注释列在个位数日期上抖动;月份顺序仍跟随应用语言
(中文界面为 2026/08/08)。

* fix(windows): Git Blame 标注改 yyyy/M/d + 日期在前,行号右键精简为行级菜单

- 日期改为不补零的 yyyy/M/d(与 macOS 一致),标签顺序改为「日期, 作者」
- 行号区右键改用独立精简菜单(Annotate/Hide Git Blame + Show Line History),
  不再弹出完整编辑器菜单;内容区菜单保留行历史、不再出现 Annotate
- 新增 gutter-context-menu 构建器与单测

* feat(windows): 行号 gutter 菜单对齐 IDEA annotate 菜单并扩大命中范围

- 菜单项按 IDEA 分组:Annotate/Close Annotations、Show Diff、Copy Revision Number,
  分隔线后是 Show Line History;提交相关项只在已注释且该行有提交时出现
- 关闭注释改名为 Close Annotations / 关闭注释,新增 showDiff/copyRevision/revisionCopied 词条
- 右键命中范围从行号列扩大到整个 gutter(行号、变更标记列、字形边距)
- gutter-context-menu 单测覆盖分组顺序与可见性条件

* fix(windows): Git Blame 注释去掉日期与作者之间的逗号

标签改为「yyyy/M/d 作者」,两者之间只留一个空格;行号列仍整体右对齐。

* fix(windows): Git Blame 注释标签改为左对齐,行号保持右对齐

标签贴注释列左侧、超长省略号截断,行号仍贴列右边缘(与 macOS 布局一致)。

* fix(windows): Git Blame 日期与作者间留两个空格,注释列宽按最长标签自适应

- 标签改为「yyyy/M/d  作者」(两个空格),去掉逗号感
- 行号列宽不再固定 26 字符:取最长标签宽度(中文按双宽)+ 4 个行号格,
  夹在 12–26 之间,短名字不再白占一列
- 新增 gitBlameColumnChars 与中日韩双宽计算的单测

* feat(windows): 注释点击定位到 Git Log,内容菜单新增 Git 子菜单

- 点注释改为打开 Git Log 并选中该行提交(新增 git-log-reveal store 传递请求,
  日志按页向前加载直到命中,最多 20 页)
- 行号右键菜单移除 Show Line History,只保留注释与提交动作
- 内容区右键新增 Git 子菜单:Annotate/Close Annotations、Show Diff、
  Copy Revision Number、Show Line History
- 补充 reveal store、gutter 菜单与编辑器 Git 子菜单单测

* fix(windows): 只读 diff 视图内 Ctrl+C/Ctrl+X 交回 Monaco 原生复制

只读 diff(提交预览、工作树差异、独立 diff 面)里的选中文字此前无法复制:
编辑器 keymap 在捕获阶段拦下 Ctrl+C 并执行源编辑器的 editor.copy,
复制的是源编辑器模型(通常为空),原生复制被 preventDefault 掉。

- diff 面根节点标记 data-readonly-diff
- keymap 在命中该区域时不再拦截 copy/cut,交给 Monaco 原生处理
- 新增 shouldDeferClipboardToReadOnlyDiff 与单测(含粘贴/带 Shift 不受影响)

* chore(windows): review 收尾——常量移出 import 区,补齐矩阵证据与验收项

* docs(matrix): Windows Git Blame 记为实现并已验证

2026-10-30 维护者在 Windows 实机确认:行号右键精简菜单、每行 yyyy/M/d  作者 注释
与自适应列宽、点注释跳转 Git Log、Show Diff 两侧复制、未跟踪与只读预览不出现入口。

* fix(windows): Git Blame 注释列补一格余量,避免最长标签被省略号截断

Monaco 的行号列宽按 cells × maxDigitWidth 四舍五入,而标签宽度受 CSS 的
calc(100% - 4ch) 限制;余量为 0 时最长标签会超出不到 1px 而被省略号截断
(截图里 2026/10/29 的日期被截成 chenb…)。

- 列宽改为标签格数 + 行号格数(按行号位数取 max(4, 位数))+ 1 格余量
- gitBlameColumnChars 改为接收条目 Map,以便按最后一行判断行号位数
- 补 5 位行号与余量的单测

* fix(windows): Git Log 定位请求在翻页无进展时结束,不再挂起

评审观察项 1:当 hasMore 为真但分页游标为空(一次失败的翻页会留下这种状态)时,
loadMore() 静默返回、effect 不会重跑,待处理的定位请求会一直挂着,可能在之后
一次刷新时突然跳到旧提交。

- useGitLogController 的 load()/loadMore() 改为返回"本页是否新增提交";
  refresh() 维持 Promise<void>
- 定位 effect 在 loadMore 解析为 false 时清空请求
- 补 integration 测试:分页返回是否推进 + 耗尽后返回 false

* fix(windows): locate-current-file ignores active paths spelled differently from the tree (#1578)

* fix(windows): match locate-current-file against the tree's path spelling

Add toRootedPath, which respells a path inside the workspace root with the root's own prefix and separator, and use it when revealing the active file in the project tree.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Add tests for toRootedPath function

Added tests for the toRootedPath function to ensure it correctly respells paths with the specified root prefix and separator.

* fix(windows): reveal the active file using the tree's path spelling

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* test(windows): locate resolves a forward-slash path against a backslash tree

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* docs(matrix): record Windows locate-current-file path handling

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-authored-by: lick <2188718831@qq.com>

* perf(windows): 优化文件打开与编辑器交互性能 (#1607)

* perf(windows): 优化文件打开性能与编辑器生命周期

- 复用 Monaco 编辑器表面与模型,保留隐藏标签布局并按可见性调度语言服务
- 缓存主题定义、静态编辑器样式和输入配置,减少全窗口样式与布局计算
- 仅为未保存编辑发送 Spring、MyBatis 索引覆盖,合并扫描并跳过无 XML 映射的工作区
- 稳定文件树、快捷键和拖放回调,减少布局测量、重绘与原生监听注册
- 文件读取使用原始二进制响应,合并前端日志 IPC 并保留上游异步文件操作
- 优化标签菜单渲染,新增最近最少使用关闭策略,默认标签上限调整为 20
- 修复模型复用后的浮层位置解析,同步国际化、能力矩阵与回归测试

* fix(windows): 合并标签上限实现并修复编辑器复用的泄漏与状态问题

- 标签上限只保留 selectBuffersOverTabLimit 一份逻辑:store 不再保存设置副本,
  改为读取真实设置和关闭策略;标签栏不再关闭终端和 Agent 标签;0 表示不限制
- 默认上限定为 30,并按测量结果说明理由;已保存的配置不变
- Monaco addCommand 的处理函数不再捕获创建 effect 作用域,修复每个销毁的
  编辑器被留在内存里的泄漏(leaks 场景回到与 preview 相同)
- 卸载时先做模型清理再销毁编辑器,保证视口状态能保存
- 文件切换时关闭行号和行历史菜单;文本未就绪时不挂 Vim;模型绑定后补设诊断
- 新增 fileOpen 性能场景和预算,新测试接入 Windows CI,补功能矩阵和 Agent Note

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: zhengfuping <fuping.zheng@onmicro.com.cn>
Co-authored-by: lick <2188718831@qq.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>

* fix(windows): 在 Quick Open 中搜索 Spring 接口路由 (#1475) (#1522)

* fix(windows): 在 Quick Open 中搜索 Spring 接口路由 (#1475)

- 默认 Quick Open 合并 Spring 接口与文件结果,复用现有 spring.index,不新增注解解析器
- 支持按路由精确/前缀/包含、控制器、处理函数和 HTTP 方法组合搜索
- 接口结果参与统一键盘导航,回车打开控制器注解行;@/# 模式不混入接口
- 校验 Spring 索引与当前工作区根一致,补充 i18n、能力矩阵、Agent Note 和回归测试

* test(windows): 同步 Quick Open 接口搜索文案断言

* fix(windows): 补齐 Spring 路由搜索边界 (#1475)

- 多 HTTP 方法分别与路由组合匹配,避免仅单个方法可命中

- Quick Open 在索引非 ready 状态隐藏旧接口结果

- 补充多方法查询和刷新失败回归测试并同步 Agent Note

* fix(workspace): avoid main-thread linear lookups on external file batches (#1598)

External file-change refreshes checked project membership with a linear
scan over the whole inventory, standardizing URLs on every comparison.
On large workspaces this kept the main thread busy after each batch.

- Keep standardized file paths and ancestor directory paths in sets,
  rebuilt only when the project inventory changes.
- Deduplicate changed URLs with a set instead of repeated contains checks.
- Record external-change history in one actor call per batch, pruning
  expired snapshots only until the first snapshot is written.
- Add regression tests for a 4000-file edit batch, batched history
  recording with skipped files, and cancelled batches.

Co-authored-by: Claude Haiku 5.5 <noreply@anthropic.com>

* fix(run): 读取登录 shell 环境并按项目 Java 版本精确挑选 JDK (#1612)

* fix(run): 读取登录 shell 环境并按项目 Java 版本精确挑选 JDK

从 Finder 启动的 Lithe 只继承 launchd 的最小 PATH,mise/SDKMAN/asdf/fnm/Homebrew
安装的 Maven、JDK、Node 都找不到;自动选 JDK 时 JAVA_HOME 只要不低于项目版本就胜出,
Java 8 项目会跑在 JDK 21 上。做法参考 OpenIDEA(Apache-2.0),出处见 NOTICE。

- macOS:启动时读取 $SHELL -ilc 的环境;只把 PATH 缓存到 Caches,热启动用缓存并后台刷新;
  其余变量只在内存中补齐缺失键,经 MacRuntimeLocator、MacManagedProcess 与 JDT 发现生效。
- Core:select_java_candidates 改为同主版本优先、其次最旧的更新版本,来源优先级只在同版本内比较;
  更新共享 fixture 与契约文档。
- 发现:macOS 增加 mise/asdf/~/.jdks JDK 与 SDKMAN/mise/asdf Maven,跳过 shims;
  Windows 增加 mise/asdf/Scoop/Semeru/OpenJDK JDK 与 mise/asdf/SDKMAN/Scoop Maven。
- 新增 NOTICE、Agent Note、功能矩阵条目与测试。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(run): end the login shell's process group on timeout and log read outcomes

- Read the login shell through MacManagedProcess so a timeout or shell exit
  also ends jobs the rc file left running; keep stdout as raw bytes and
  discard stderr so one non-UTF-8 greeting cannot void the read.
- Record each startup/refresh read (shell name, source, duration, variable
  count; never values) in the application log, buffering the startup record
  until the log writer attaches.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>

* fix(macos): 更新下载断点续传,失败提示区分原因 (#1609)

* fix(macos): 更新下载断点续传、区分失败原因,本地历史限制 100MB

- Sparkle 下载经本机回环转发 UpdateDownloadRelay:Range + If-Range 续传,断点存 Caches,
  跨会话保留;206 时自行核对 ETag/Last-Modified,防止 GitHub CDN 无视 If-Range 拼出坏包
- 下载失败区分超时、无法连接、服务器错误,并提示已下载数据会保留、重试可继续
- 启动时清理已完成或废弃的回退暂存目录
- 本地历史每个项目上限 100MB(基线最多 50MB),基线跳过生成目录与嵌套仓库,
  保存时清理旧版本遗留的基线,超限按基线→编辑→标签由旧到新淘汰
- 新增 scripts/release/sparkle/test-sparkle-relay-e2e.sh:本地服务器 + 真实 Sparkle 五场景端到端

* chore: 本地历史上限拆到 #1610,本 PR 只保留更新下载改动

---------

Co-authored-by: lick <2188718831@qq.com>

* fix(core): 本地历史每个项目限制 100MB,基线跳过生成目录 (#1610)

- 每个项目上限 100MB(按 4KB 分配块计,占用量进程内缓存),其中项目基线最多 50MB
- 基线跳过 node_modules、.venv、target、.claude、.uv-cache 等生成目录和嵌套 Git 仓库
- 保存时清理过期条目和旧版本遗留的排除目录基线;超限按基线→编辑→标签由旧到新淘汰

Co-authored-by: lick <2188718831@qq.com>

* feat(macos): 设置中可配置正式版更新源 (#1611)

* fix(macos): 更新下载断点续传、区分失败原因,本地历史限制 100MB

- Sparkle 下载经本机回环转发 UpdateDownloadRelay:Range + If-Range 续传,断点存 Caches,
  跨会话保留;206 时自行核对 ETag/Last-Modified,防止 GitHub CDN 无视 If-Range 拼出坏包
- 下载失败区分超时、无法连接、服务器错误,并提示已下载数据会保留、重试可继续
- 启动时清理已完成或废弃的回退暂存目录
- 本地历史每个项目上限 100MB(基线最多 50MB),基线跳过生成目录与嵌套仓库,
  保存时清理旧版本遗留的基线,超限按基线→编辑→标签由旧到新淘汰
- 新增 scripts/release/sparkle/test-sparkle-relay-e2e.sh:本地服务器 + 真实 Sparkle 五场景端到端

* chore: 本地历史上限拆到 #1610,本 PR 只保留更新下载改动

* feat(macos): 设置中可配置正式版更新源

- 外观与行为 > 更新新增「更新源」,默认是仓库最新 Release 下载目录
- 镜像需平铺提供同名 appcast-<arch>.xml 与更新包,Sparkle 仍校验签名
- 输入先测试连接(读取清单并 HEAD 最新归档),成功后才能应用;可恢复默认
- 下载失败与连接测试的提示带出镜像主机名
- AutoBuild 安装或选择 AutoBuild 渠道时禁用,始终用官方源

---------

Co-authored-by: lick <2188718831@qq.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: arkleselect <166632698+arkleselect@users.noreply.github.com>
Co-authored-by: Xiaoyumuxi <23722032@bjtu.edu.cn>
Co-authored-by: 大德 <zher52@aliyun.com>
Co-authored-by: lincoco <77844710+lin-coco@users.noreply.github.com>
Co-authored-by: 若水 <frankw.wang@qq.com>
Co-authored-by: waani <kuun993@163.com>
Co-authored-by: AACS111 <103710223+AACS111@users.noreply.github.com>
Co-authored-by: zhengfuping <fuping.zheng@onmicro.com.cn>
Co-authored-by: puppyben1 <136492871+puppyben1@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants