Skip to content

fix(desktop): 卸载插件前等待构建、VCS 和调试会话退出 - #1921

Merged
1lck merged 1 commit into
previewfrom
codex/fix-1843-plugin-uninstall-lifecycle
Nov 14, 2026
Merged

1lck merged 1 commit into
previewfrom
codex/fix-1843-plugin-uninstall-lifecycle

Conversation

@1lck

@1lck 1lck commented Nov 14, 2026 •

Copy link
Copy Markdown
Owner

关联 Issue / Linked issue

PR 类型 / Type

  • feat:新功能或用户可见的改进
  • fix:缺陷修复
  • docs:文档、Agent Note、Skill 等规则文件
  • release:稳定版发布准备

改动说明 / What changes

背景 / Why

插件提供的构建、版本控制或调试进程仍在运行时卸载插件,旧流程只等待语言服务器和插件后端,再删除插件包与状态;构建清理发生在删包后的界面回调,VCS 和调试适配器没有加入卸载等待。在 Windows 上可能因可执行文件仍被占用而删包失败,在其他平台也可能重新写回已经删除的状态。

现在先阻断该插件的原生启动,取消并等待启动中的任务,再等待已运行的提供者与调试适配器退出,最后执行 Core 已有卸载计划中的文件删除。停止失败时保留插件包、批准记录和状态。

改动 / Changes

  • plugin_programs.go 登记并取消构建/VCS 的原生启动;启动完成或迟到进程清理结束后才释放等待。已登记提供者清理失败时保留句柄,供下一次停止重试;无法确认的迟到启动清理失败继续阻断删除。
  • 卸载收集当前窗口所有项目标签的原生所有者,包含隐藏标签;等待各自的构建、VCS、调试、语言服务器及后端清理。成功后刷新每个标签的插件状态和目录,失败时保留提供者登记,不通过目录刷新丢掉失败句柄。
  • 构建和 VCS 启动在创建状态目录前登记;取消后不发布新会话,迟到会话使用独立的有界清理上下文,避免拿已取消的启动上下文停止进程。提供者握手失败时保留并返回清理错误。
  • VCS 列表刷新保留启动阻断;显式启用或确认安装时,即使旧会话对象已被刷新移除,也恢复保留的启动入口。
  • 调试会话发布清理完成信号,卸载等待原生退出及现有 Run 清理;沿用原先的父子会话、Core 销毁和 Run 停止顺序,阻止已摘除插件启动新适配器。
  • Manager.Apply 在 stopPrograms 失败时立即返回,保留后续文件和批准记录;其他步骤沿用 Core 的既有计划。
  • 增加停止失败保留文件、调试适配器退出顺序、构建/VCS 销毁顺序、隐藏标签迟到启动、目录刷新后拒绝启动,以及重新启用恢复 VCS 的回归测试。测试仅用虚构清单、受控事件和复制的测试程序。
  • 更新现有卸载决策 Note 和宿主插件管理能力矩阵,两平台验证状态仍如实保留 pending。

不在本 PR 范围内 / Out of scope


类型专属:fix

复现与根因

  • 复现:启动虚构插件的调试适配器或构建/VCS 提供者后卸载。修复前包可在适配器退出前被移除;停止回调返回错误后,包、状态和批准记录仍被删除。期望等待退出,停止失败则保留文件。
  • 根因:fix(desktop): 确认安装即启用插件,卸载先停进程再清理插件状态目录 #1846(549696fdb)的卸载生命周期只传入语言服务器和后端停止;其他原生所有者没有参与删包前的等待。之后 Core 计划的执行器沿用“收集错误并继续步骤”,没有在原生停止失败时阻止文件删除。
  • 影响平台:macOS/Windows 共用 Viva Go 原生适配代码;本次自动化运行平台为 macOS。Windows 文件锁与原生窗口流程未执行,不声明该平台已验收。

检查项

  • 已先写回归测试,确认它在修复前失败、修复后通过;pluginmanager_test.go:TestUninstallPreservesFilesWhenProgramsCannotStop 旧版失败为包和状态不存在、批准记录丢失;plugins_test.go:TestUninstallWaitsForTheDebugAdapter 旧版失败为 the package was removed before its adapter exited。提交前补充的 TestEnableReopensVcsAfterCatalogRefresh 先失败为 build provider session is closed,再修复保留启动入口的恢复。
  • [N/A] 无法自动化时,已写明手动复现与验证步骤:上述行为已自动化;Windows 原生验证限制及步骤见下方。
  • 已搜索被修改函数、类型、契约字段的全部调用方(含另一平台、插件、SDK、脚本和按字符串分发的调用):检查 Service.Uninstall、Manager.Apply、buildProvider、vcsRuntime.session/runtime、releaseDebugSession、beginDebug、安装与启用完成回调及所有项目标签调用链;无插件协议变更。
  • 已检查另一平台是否有同类缺陷:两端执行同一份修复,未引入平台分支;Windows 原生验证仍待执行。
  • 只改了修复所需的代码,没有夹带重构;独立并发事务债务已提交 [Feature] 将同一插件的安装、启停与卸载改为跨项目标签的串行事务 #1918。
  • 修复改变了行为约束或容易复发,已在 .agents/notes/implemented/bug-fix/2026-11-13-viva-plugin-install-enables-and-uninstall-cleans-state.md 记录。

范围检查 / Scope checks

功能矩阵 / Feature matrix

  • 已更新 shared/platform-feature-matrix/features/plugin-extension-management.json 的证据与行为说明,两端状态如实保留 partial/pending。
  • 已运行矩阵校验与相对最新 origin/preview 的能力变更门禁。
  • 没有提交 .artifacts/ 下生成的矩阵视图。
  • [N/A] 没有更新矩阵的理由:已更新,不申请 matrix-exempt。

插件归属 / Plugin ownership

  • 已运行宿主零依赖自查命令,结果为空。
  • 新增测试只使用 dev.lithe.test.* 虚构清单与宿主可控的测试进程,不读取具体插件包、仓库或真实 ID。
  • 只更新宿主通用插件管理能力,证据不引用具体插件内容。
  • 未添加插件文案、插件构建或资源说明。
  • [N/A] 受影响插件仓库测试:本次没有修改公共扩展点、消息协议或插件逻辑;验证宿主自己的进程停止与删包顺序,不依赖具体插件。

统一日志系统 / Structured logging

  • [N/A] 新事件目录与生成类型:未新增事件,停止错误汇总交给既有 plugin_uninstall/debug 的统一操作失败边界;未新增 print、stderr 或新日志通道。
  • 提供者清理错误不再被忽略,交由操作失败边界报告;调试清理沿用原有诊断边界;高频路径未新增 INFO 输出。
  • 未新增源码、编辑内容、环境变量值、命令输出或凭据日志。
  • 旧日志生成及使用门禁已移除;等价检查未恢复,明确标记日志门禁未完成([Feature] 恢复 Viva 日志事件类型生成和目录使用门禁 #1802),未记为通过。

界面文案 / i18n

N/A:没有新增或修改面向用户的文字,继续使用既有本地化错误与提示接口,未修改生成器或豁免。

逻辑归属 / Logic placement

  • 卸载步骤仍来自 Core plugins.installed.lifecycle;Go 只执行/等待原生进程和文件 I/O,不引入插件业务规则。
  • [N/A] 迁移平台层共享规则:本次新增登记表保存的是原生客户端、取消句柄及完成事件;失败后停止文件删除属于原生 I/O 安全边界。多个生命周期事务的共享规则由 [Feature] 将同一插件的安装、启停与卸载改为跨项目标签的串行事务 #1918 单独跟踪。
  • 没有工具、运行时或具体插件名称分支。

性能与内存 / Performance and memory

  • 仅实际启动任务时登记资源,无轮询、新常驻线程、预启动进程或依赖;完成后释放登记,失败则保留必要的清理信息。
  • 进程停止、等待和文件删除在后台执行;窗口线程只摘除句柄与阻断启动,不增加磁盘扫描或进程等待。
  • [N/A] 编辑器等热路径性能基线:未改动这些路径;无新增运行时或大型依赖,无安装包体积变化。

设置 / Settings

N/A:未新增或修改设置项、设置页、工具配置来源或对话框选项。

插件契约 / Plugin contract

N/A:未修改 Core 契约、能力版本、插件后端协议、SDK、宿主方法或通知;无需 API 实施计划表或 Core pin 升级。

发行包与资源 / Bundle and resources

  • 未新增资源路径,不向发行目录写入;已运行 macOS/Windows 源码的 runtime bundle immutability 静态检查。
  • [N/A] 资源复用清单、下载与缓存说明:无新增或修改的下载、解压、生成或缓存资源,仅修正既有原生资源清理顺序。

无用代码与重构 / Dead code and refactoring


验证 / Verification

命令或操作 平台 结果
修复前两条原始卸载回归 macOS 均失败,证明过早删包及停止失败后仍删文件
TestEnableReopensVcsAfterCatalogRefresh 修复前检查 macOS 失败为 provider session is closed,证明恢复入口缺口
之前基线的 desktop-go.sh test -json ./... -count=1 -timeout=300s -p 2(逐项 HTML/JUnit) macOS 3545 通过、11 跳过、无失败;55 个有测试包
之前基线的相关 -race 卸载、安装、调试清理与 detach 测试 macOS 通过,无竞态
最新 preview 基线的 desktop-go.sh test -json ./... -count=1 -timeout=300s -p 2(逐项 HTML/JUnit) macOS 3561 通过、11 跳过、无失败,235.3 秒,进程树终止已确认
最新基线:desktop-go.sh test -race ./internal/buildprovider ./internal/pluginmanager ./internal/pluginservice -count=1 -timeout=120s macOS 全部通过,分别 6.943s / 3.250s / 5.572s
最新基线:desktop-go.sh test -race ./internal/workbench -run 'Test(Uninstall|ConfirmedInstall|DebugReleases|BuildRuntimeDetach|EnableReopensVcsAfterCatalogRefresh)' -count=1 -timeout=120s macOS 通过,15.772s,无竞态
功能矩阵内容与变更门禁、测试稳定性静态门禁、Agent Notes、运行时发行目录只读检查、宿主零依赖自查、git diff --check macOS 通过

未能执行的检查和原因:

  • Windows 原生环境未运行。待验证:在项目标签中运行构建/VCS/调试提供者,隐藏一个标签后卸载;确认所有相关进程先退出再删包和状态,重新安装/启用仍可启动 VCS。停止失败时文件保留。
  • 日志生成及目录使用门禁当前缺失([Feature] 恢复 Viva 日志事件类型生成和目录使用门禁 #1802),未记为通过。
  • 依用户要求沿用跳过 CI,提交和压缩合并提交包含 [skip ci];合并以本地验证为依据。

提交前自检

未发现需要阻塞合并的问题。已检查原生句柄归属、状态目录创建前登记、迟到启动清理、UI/后台线程边界、失败保留与重新启用恢复;自检中发现的 VCS 恢复入口问题已补回归并修复。存量并发生命周期债务保留在 #1918,不关闭该 Issue。

提交前确认 / Final checks

  • 分支从 preview 创建,已同步最新 preview 059d878d4;目标分支 preview。
  • 以 Draft 提交,本地最终验证通过后才标记 ready。
  • 仅包含本次修复及其测试、Note、矩阵,无产物、凭据、个人路径或诊断日志。
  • 最终构建、测试应用和子进程已关闭;按进程名核对 Lithe、提供者、适配器及各相关测试程序,残留为 0。

@ghfind-review ghfind-review Bot added the review: high ghfind author score; see https://ghfind.com label Nov 14, 2026
@1lck
1lck marked this pull request as ready for review November 14, 2026 12:09
@1lck
1lck merged commit 920fe94 into preview Nov 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant