Skip to content

feat(desktop): 设置新增“关于”页,更新改为 Motty 式检查与一键更新,版本区分正式版与预览版 - #1900

Merged
xiaoyumuxi merged 1 commit into
previewfrom
feat/desktop-settings-about-page
Nov 14, 2026
Merged

xiaoyumuxi merged 1 commit into
previewfrom
feat/desktop-settings-about-page

Conversation

@xiaoyumuxi

Copy link
Copy Markdown
Collaborator

关联 Issue / Linked issue

PR 类型 / Type

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

改动说明 / What changes

背景 / Why

Viva 设置里没有“关于”页(#1620),用户看不到自己用的是哪个版本、怎样更新、去哪里交流。原来的更新只在启动时每天检查一次、只提示,要到更新页手动下载安装。欢迎页和设置里显示的“Core 0.1.0”其实是 Core C ABI 的版本,不是应用版本,会误导用户;而且没有任何地方能区分正式版和预览版。

做法参照 Motty:新增一级“关于”页;更新改为启动后不久检查、之后每小时检查,一键“更新”;版本统一显示为 desktop/viva.toml 里的应用版本(0.7.0),只有 Desktop Release 用 desktop-v<版本> 标签构建的包显示纯版本号,其余构建都显示“0.7.0 预览版”。

改动 / Changes

关于页(desktop/internal/settingswindow)

  • model.go:新增一级页面 pageAbout,固定在侧栏 AI 之后,面包屑只有“关于”一级;palette.go 给它配了青色的 Info 图标。
  • about_view.go(新):
    • 页头:图标、名称、简介和“复制”按钮。复制版本、平台、构建、运行时四行文字,用于提交 Issue;复制成功时按钮显示“已复制”,失败时显示原因,并以 settings_about_copy 记日志。
    • 版本信息:版本(带“预览版”标签);平台(macOS · arm64 / Windows · x86-64 等,用人能读懂的叫法);构建(提交前 7 位 · 日期,来自 Go 记录的 vcs.revision/vcs.time;没有记录时页面显示“未记录”,复制内容省略这一行);运行时(Go 版本)。
    • 更新:与“外观与行为 › 更新”共用同一张卡片和状态。
    • 加入交流:QQ 群 163027877、微信群(飞书页面)。
    • 项目:源码仓库、Issue。
    • 不显示 Discord 和官网。
    • 链接都指向官方仓库或官方交流群页面。
  • updates_view.go:
    • 更新卡片抽成可复用组件,关于页和更新页共用。
    • 当前版本按正式版/预览版显示。
    • 按状态显示:检查中、已是最新、有新版本、下载进度百分比、已下载、正在安装。
    • 按钮有“立即检查”、“更新”,下载中还有“取消”。
  • 修复关于页在纯文字上挂 Tooltip 导致的崩溃。
  • 设置窗口的失败改为带操作名上报,Options.SettingsError 由 func(error) 改为 func(operation string, err error)。以前快捷键方案、编辑器偏好、关于页复制的失败都被记成 plugin_settings_surface,现在分别记 keymap_schemes、editor_preferences、settings_about_copy;插件设置仍记 plugin_settings_surface。

更新(desktop/internal/workbench/updates.go)

  • 自动检查:
    • 启动 5 秒后第一次检查,之后每小时一次,只有一个定时器。
    • 到点时窗口在后台,就推迟到窗口回到前台再补检查(window_sessions.go 在激活时调用 resumeUpdateCheck),空闲的 Lithe 不会每小时为没人看的窗口读 feed。
    • 同一版本只通知一次。
    • 自动检查失败不在页面显示,只记日志 update_check;用户点“立即检查”时才显示原因。
  • “更新”一键完成:
    • 下载到用户缓存目录 Lithe/Updates/<版本>。
    • 校验签名、大小和 SHA-256,沿用 Viva appupdate。
    • 像退出一样关闭各项目标签(未保存文件会询问),然后安装并重启。
    • 下载中可以取消:取消后恢复为“可更新”,不报错(log-exempt)。
  • 一个窗口的所有项目标签共用一份 *updater:app.go 里新标签复用 first.updates。saveSettings 写入 updater.store,所以无论哪个标签保存,写下的都是窗口的“自动检查”开关和上次检查时间。窗口关闭时 stopUpdates 撤销定时器并停止下载。
  • 日志:
    • 失败:update_check、update。
    • 用户操作:updates.check、updates.update、updates.cancel。

版本标识(正式版 / 预览版)

  • desktop/internal/buildinfo:新增 Stable,由 lithe_stable 构建标签决定(stable.go / preview.go)。
  • scripts/desktop/package-desktop.sh:新增 --stable,打包时加上 lithe_stable 标签。
  • scripts/ci/desktop-release/package-release.sh:
    • 只有这里传 --stable,macOS、Windows、Linux 都传。
    • 由推送标签触发时,校验 desktop-v<版本> 标签就在 HEAD 上。
    • 每个打包出来的程序都用 go version -m 确认带有 lithe_stable,没有就失败。
  • 欢迎页(welcome_view.go)、关于页、更新页和复制内容按同一规则显示版本:正式版显示“0.7.0”,其余(desktop-AutoBuild、本地打包、go run)显示“0.7.0 预览版”。
  • 删除 Kernel.Version(),不再显示 Core C ABI 版本“0.1.0”。

其他

  • settings.go:新增 openSettingsLink,关于页的链接都从这里打开。打开失败时通知用户并记日志 settings_open_link,成功记用户操作 settings.openLink。
  • 图标:在 generate-desktop-icons.sh 里加入 lucide 的 github、monitor、external-link、message-circle、messages-square,并重新生成 icons.go。
  • i18n:关于页、更新状态、预览版标签的中英文词条加在 shared/i18n/,生成文件已重新生成。i18n.App.Version(version, stable) 统一拼出版本文字。
  • 修复既有的偶发失败 TestProjectTreeCreatesRenamesAndDeletes(feat(desktop): 右键删除改为弹窗选择移到废纸篓或永久删除,复制路径收进二级菜单 #1894 引入):高负载下打开删除对话框后没有请求重绘,测试点击时那一帧里还没有“永久删除”按钮。现在先请求重绘,并有界等待按钮出现再点击。
  • 文档:
    • 设置分类 Note 加入“关于”的归属规则:一级页面,固定在最后,不放设置项。
    • release-lithe Skill 写明只有 Desktop Release 传 --stable。
    • docs/viva-migration.md 的发布工作流一行同步更新。
  • 功能矩阵:新增 settings-about-page.json,更新 updates-check-download.json。

不在本 PR 范围内 / Out of scope


类型专属:feat

多平台对齐

  • 两端都具备:合入后 macOS 与 Windows 都具备该能力。关于页、更新器和版本标识都是 macOS 与 Windows 共用的 Viva 代码,package-release.sh 三个平台都传 --stable。Windows 只有无头测试覆盖,未在实机验证(见“验证”)。

范围检查 / Scope checks

功能矩阵 / Feature matrix

  • 已更新 shared/platform-feature-matrix/features/<id>.json:新增 settings-about-page,两端 implemented / pending(无实机验收);updates-check-download 补证据路径、自动化测试说明和新行为,验证状态保持不变
  • 已运行 ./scripts/platform-feature-matrix/verify-platform-feature-matrix.sh 和 ./scripts/platform-feature-matrix/verify-platform-feature-matrix-change.sh origin/preview HEAD
  • 没有提交 .artifacts/ 下生成的矩阵视图
  • [N/A] 没有更新矩阵的理由:已更新

统一日志系统 / Structured logging

  • 已接入统一日志系统:只用 Core 目录里已有的 app.operation.failed 与 app.action.performed,通过 a.emit / a.performed 记录,没有手写事件 ID、直接写 stderr 或 print。新增的操作名和用户操作都加进了 TestLogEventsMatchCatalog,由测试按 Core 目录校验:update_check、update、settings_about_copy、settings_open_link、editor_preferences、keymap_schemes、plugin_settings_surface,以及 updates.check、updates.update、updates.cancel、settings.openLink
  • 一个操作只有一条终态,错误只在处理它的边界记录一次:自动检查失败只记日志不弹提示;取消下载不是失败(log-exempt);进度按整百分比刷新界面,不写日志
  • 没有记录源码、编辑内容、环境变量值、命令输出、凭据;错误用 error 类型
  • [N/A] node scripts/logging/generate-log-events.mjs --check、node scripts/logging/verify-log-usage.mjs:两个脚本已随 Epic(0.7.0): 基于 Viva 框架的跨平台方案的迁移(#1794) #1799 删除,恢复由 [Feature] 恢复 Viva 日志事件类型生成和目录使用门禁 #1802 跟进;改为由 TestLogEventsMatchCatalog 校验

界面文案 / i18n

  • 文案都走共享 i18n:中英词条加在 shared/i18n/,已运行 node scripts/i18n/generate-i18n.mjs 并提交生成结果,没有手改生成文件
  • 已运行 node scripts/i18n/verify-app-language-localization.mjs 和 node scripts/i18n/generate-i18n.mjs --check,没有放宽脚本或扩大豁免名单

逻辑归属 / Logic placement

  • 本 PR 没有新增可共享的业务逻辑:
    • 应用自更新只服务于这个 UI 壳本身,换壳后整套更新会随之替换。定时、窗口激活和标签共享都绑定 Viva 窗口生命周期;签名、校验、语义化版本比较和安装来自 Viva 上游 appupdate。
    • 正式版 / 预览版是构建身份(构建标签),不是运行期规则。
    • 关于页的平台、构建、运行时读取的是 Go 运行时和构建信息,属于平台层呈现。
  • [N/A] 修改平台层已有的可共享逻辑:没有改动可共享逻辑
  • 工具或运行时专属的知识放在插件或成熟上游,宿主和 Core 没有按工具名加分支

性能与内存 / Performance and memory

  • 没有新增空闲轮询:
    • 只有一个定时器,每小时一次;窗口在后台时到点不检查,回到前台才补。
    • 窗口关闭时撤销定时器并停止下载。
    • 下载进度按整百分比刷新。
  • 主线程没有网络和目录操作:检查 feed、创建缓存目录和下载都在 goroutine 里,结果通过 post 回到窗口线程。每次检查后保存设置时,沿用原有 saveSettings 在窗口线程写设置文件(改动前的更新器就是这样,每小时最多一次);设置持久化的所有权由 [Feature] 统一 Viva 应用偏好所有权与多窗口发布,避免独立快照继续使用或覆盖旧设置 #1851 处理
  • [N/A] 性能基线:没有改动启动、打开项目、输入、滚动、大文件、长输出或搜索;没有新增运行时或依赖(新增 5 个矢量图标)

设置 / Settings

  • 难以理解的项有 ⓘ:关于页只展示信息,没有可修改的配置;自动检查开关仍在“外观与行为 › 更新”,未改
  • [N/A] 工具真实配置来源:本 PR 不涉及工具配置
  • 新增设置页的归属已按设置分类 Note 确定(“关于”是固定在最后的一级页面,不放设置项),Note 已同步更新

插件契约 / Plugin contract

N/A:不涉及插件契约、能力版本、插件函数协议或宿主方法。

发行包与资源 / Bundle and resources

  • 运行时不向已安装的 app bundle 或 Windows 安装目录写入:更新下载放在用户缓存目录 Lithe/Updates/<版本>(os.UserCacheDir),生命周期为下载到安装,属于更新器;已运行 ./scripts/desktop/verify/verify-runtime-bundle-immutability.sh
  • [N/A] worktree 资源复用清单:没有新增构建期下载、解压、生成或缓存资源(图标由已有生成脚本生成并提交源码)

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


验证 / Verification

命令或操作 平台 结果
scripts/desktop/desktop-go.sh test -count=1 ./internal/settingswindow ./internal/buildinfo ./internal/i18n macOS arm64 通过
scripts/desktop/desktop-go.sh test -count=1 ./internal/workbench macOS arm64 通过(140 s)
scripts/desktop/desktop-go.sh test ./...(在设置失败操作名改动之前的版本上;之后 settingswindow 与 workbench 已重跑) macOS arm64 通过
scripts/desktop/desktop-go.sh test -race -count=1 ./internal/settingswindow ./internal/workbench -run 'TestAbout|TestUpdatesPageNames|TestUpdateLineSays|TestWelcomeTitleAndVersion|TestAutomaticUpdateCheck|TestUpdateCheckFailure|TestCancelledUpdateDownload|TestTurningOffTheAutomaticCheck|TestLogEventsMatchCatalog' macOS arm64 通过
scripts/desktop/desktop-go.sh vet ./internal/settingswindow ./internal/workbench ./internal/buildinfo(默认,以及 -tags lithe_stable) macOS arm64 通过
node scripts/i18n/generate-i18n.mjs --check、node scripts/i18n/verify-app-language-localization.mjs macOS 通过(中英 11105/11105)
./scripts/platform-feature-matrix/verify-platform-feature-matrix.sh、verify-platform-feature-matrix-change.sh origin/preview HEAD macOS 通过(224 项)
./scripts/agent-notes/verify-agent-notes.sh macOS 通过(221 篇)
./scripts/desktop/verify/verify-runtime-bundle-immutability.sh macOS(静态检查覆盖 macOS 与 Windows 源码) 通过
.agents/skills/write-stable-tests/scripts/verify-test-stability.sh --base origin/preview macOS 通过
test-stability-macos.sh:workbench TestProjectTreeCreatesRenamesAndDeletes|TestLogEventsMatchCatalog,settingswindow TestAbout|TestUpdatesPageNames|TestUpdateLineSays macOS 通过,单测试耗时最长 70 ms(关于页)
visual_capture_test 生成 36-settings-about 中英文、浅色与深色无头截图 macOS 已生成,未附在本 PR

未能执行的检查和原因:

  • Windows 实机:本机是 macOS,没有在 Windows 上运行。
  • 真实窗口:没有启动 Lithe 实际查看关于页和更新流程,只做了无头窗口测试。
  • 正式版安装包:没有跑 Desktop Release,--stable 和 is_stable_program 校验没有在 CI 实跑。
  • 真实更新:发行构建尚未注入更新源,没有签名 feed,无法验证真实的下载、安装和重启;更新流程用假的更新源在测试中覆盖。

提交前确认 / Final checks

  • 分支从最新的 preview 创建;目标分支:preview
  • 以 Draft 提交,本地验证通过后才标记 ready
  • 没有无关改动,没有提交 .build/、target/、dist/、.artifacts/ 等产物,没有凭据、个人路径和未脱敏的日志或截图
  • 本次没有启动 Lithe 应用,测试全部是无头运行,没有进程残留

- 设置侧栏在 AI 之后新增一级页面“关于”:图标、名称、简介和复制按钮;版本信息
  (版本、平台、构建、运行时);与更新页共用的更新卡片;加入交流(QQ 群、微信群
  飞书页);项目(源码仓库、Issue)。不再显示 Core C ABI 版本。
- 更新参照 Motty:启动 5 秒后第一次检查,之后每小时一次;窗口在后台时推迟到回到
  前台再补;同一版本只通知一次;“立即检查”与一键“更新”(下载、校验、安装、重启),
  下载中可取消。项目标签页共用一份更新状态。
- 版本号来自 desktop/viva.toml。只有 Desktop Release 为 desktop-v<版本> 标签的提交
  打包时传 package-desktop.sh --stable(lithe_stable 构建标签),应用内显示纯版本号;
  其余构建显示“<版本> 预览版”。package-release.sh 校验标签在 HEAD 上且每个打包程序
  都带 lithe_stable。
- 修复关于页在纯文字上挂 Tooltip 导致的崩溃。
- 设置窗口的失败带上真实操作名写日志(settings_about_copy、keymap_schemes、
  editor_preferences、plugin_settings_surface),不再全部记成 plugin_settings_surface;
  打开链接失败记 settings_open_link 并提示用户。
- 修复 TestProjectTreeCreatesRenamesAndDeletes 在高负载下偶发找不到“永久删除”:
  打开对话框后请求重绘,并有界等待按钮出现再点击。
- 补关于页、更新器和欢迎页版本标识的测试,日志目录测试覆盖新增事件;更新设置分类
  Note、发布 Skill、迁移文档和功能矩阵。
@ghfind-review ghfind-review Bot added the review: high ghfind author score; see https://ghfind.com label Nov 14, 2026
@xiaoyumuxi
xiaoyumuxi marked this pull request as ready for review November 14, 2026 05:51
@xiaoyumuxi
xiaoyumuxi merged commit e6df80c into preview Nov 14, 2026
6 of 8 checks passed
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