Repository navigation
Epic(0.7.0): 基于 Viva 框架的跨平台方案的迁移(#1794) - #1799
Merged
Merged
Conversation
This was referenced Nov 8, 2026
This was referenced Nov 9, 2026
10 of 13 tasks
1 task done
This was referenced Nov 10, 2026
Merged
1lck
added a commit
that referenced
this pull request
Nov 10, 2026
- core: git.write 在请求带进度观察者时订阅 Core 事件流,解析 progressDetails (阶段、阶段百分比、对象计数);新增 WithGitProgress 与 GitFetchSettingsOf (包装只读的 git.executionInspect)。 - workbench: 同步状态行显示当前阶段名、百分比和进度条,高频事件合并后再投递 到 UI 线程,取消沿用原按钮;Fetch Options 对话框打开时读取仓库 lithe.fetch.* 与应用默认值作为当前值,并显示实际标签行为,读取完成前不可提交, 打开对话框不写任何文件;配置无效或读取失败时说明原因并显示默认值。 - i18n: 补齐阶段名、进度、设置提示和标签行为的中英词条并重新生成。 - 功能矩阵:更新 git-branches-remotes 的 Viva 验证说明。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1lck
added a commit
that referenced
this pull request
Nov 10, 2026
克隆对话框、插件审核与提示、Search Everywhere、跳转行列、语义弹窗(引用/补全/悬停)、 重命名对话框和窗口通知改为同一个 overlay Page:ui.Modal/ui.Dialog、ui.List、ui.Toasts。 删除 Frame 绘制、手写 Tab 循环和 focus 还原;窗口输入统一经 pages_input.go 路由到 Page。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1lck
added a commit
that referenced
this pull request
Nov 10, 2026
欢迎页改为整屏 Page:ui.TextField、ui.Button、ui.Menu(更多)、ui.List 加 ContextMenu 与行内菜单; 最近项目分支读取改为 Page 的 Effect。Find in Files 改为面板 Page:ui.TextField、ui.Popover 选项、ui.List 结果列表,刷新按钮并入面板。删除 Frame 绘制、手写菜单与焦点、列表虚拟化。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1lck
added a commit
that referenced
this pull request
Nov 10, 2026
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1lck
added a commit
that referenced
this pull request
Nov 10, 2026
改用 Popover 挂在窗口顶部居中(y=84)的锚点上,不再有遮罩;标签页、查询框、结果列表放进浮层, 点击外部关闭并把点击交还给下面的界面。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1lck
added a commit
that referenced
this pull request
Nov 10, 2026
- Commit 工具窗口是嵌在面板 Slot 里的 Page:工具栏、变更列表、提交区用 ui.Scroll、 ui.Checkbox、ui.TextArea(绑定项目持有的 text.Editor)和 ui.Splitter,评审用 ui.ModalWith; Primary+Enter 提交改为 Box.Shortcut,删除 app.go 里按 commitMessageID 的快捷键、滚轮和文本输入分支。 - 分支弹窗、分支对话框和同步(Fetch 选项、分叉)对话框是一个覆盖整窗的 overlay Page, 在窗口 Frame 绘制之后绘制;弹窗用 ui.PopoverWith,行菜单用 ui.Menu,对话框用 ui.ModalWith, 标题栏分支按钮仍由 Frame 声明(branch_chrome.go),弹窗锚在它的矩形上。 - 新增 git_pages.go 集中路由 Pointer/Key/Shortcut/Wheel/TextInput,app.go 只加调用点。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1lck
added a commit
that referenced
this pull request
Nov 10, 2026
- 日志页是嵌在 Git 面板 Slot 里的一个 Page:引用面板用 ui.Tree,提交列表用 ui.List(行用 ui.Control 之外的 Draw 回调沿用 gitgraph.go 的图、文字与标签绘制),详情区的变更文件用带 RowWidth 的 ui.List(左右键用容器的 Shortcut 展开/折叠),分隔用 ui.Splitter, 过滤弹层用 ui.PopoverWith,操作菜单用 ui.Menu,同步状态行与取消按钮用 ui.Progress/ui.Button。 - 删除 paintGitLog/captureLogFiles/logKey/logFilesPointer 与 beginFrame/capture 的后绘制与手写分发, 提交列表上下键、选择和滚动交给 ui.List;折叠和选中状态仍在 project.log。 - 原先在面板头里的“显示全部”和 ⋮ 操作菜单并入过滤栏(头部由外壳绘制);⋮ 放在过滤栏最前, 窄面板不会把它裁掉。 - 把对话框、弹层、过滤栏、键盘与侧向滚动补成测试,并让手写滚动逻辑只在水平分量占优时才侧向滚动。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
诊断输出指出了两条真实原因: - 远程确认测试里失败信息是 “plugin package path is not usable: "adapter" does not exist”: debugPluginHarness 没像 debugHarnessWith 那样把清单里的 packaged path 换成 adapter.exe, 而拷贝的测试二进制在 Windows 上就叫 adapter.exe,于是启动前就被拒绝。 - Run 输出链接测试里文档路径是正斜杠、目标路径是反斜杠,字符串不同但同一个文件。 winpath.Equal 改为在 Windows 上把两侧展开长名后统一用 / 分隔符并忽略大小写比较。 本机 vet 通过,winpath 用 GOOS=windows 交叉编译通过。 Co-Authored-By: AtomCode (deepseek-v4.1-flash) <noreply@atomgit.com>
This was referenced Nov 12, 2026
24 of 27 tasks
This was referenced Nov 13, 2026
Closed
17 of 20 tasks
This was referenced Nov 14, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
关联
d797244(main,含 Core 优化建议 #1–feat(database): add integrated database workspace #17;scripts/desktop/build-desktop-core.sh的PINNED_CORE_REVISION)。desktop/go.mod的replace固定 fork main7850516(v0.6.1-0.20261111102951-7850516be532)。比上游多出:Window.SetTitle(优化建议 #1)、app.Config.OnFocusLost(图标优化建议 #2)、ui.MenuAt(feat: Windows Electron port + VS Code Extension Host #3)、MarkdownView 图片(lithe 0.1.12 #4,对应上游 [API] Draw images in Markdown with host-supplied bitmaps vivaui/viva#220)、改标题后红绿灯保持居中([Feature] 希望支持Mac低版本 #5,依赖 优化建议 #1,未单独提上游)、MenuItems.Beside()菜单从锚点右侧展开([Feature] 现在是支持的Spring系,希望增加支持quarkus系 #6,上游 feat(ui): add MenuItems.Beside to open a menu beside its anchor vivaui/viva#227 OPEN)。上游 fix(ui): show a List's requested scroll in the paint that applies it vivaui/viva#219、fix(windows): 稳定滚动区域视口引用 #221 已合入。当前状态
开发进行中,保持 Draft。其他开发已冻结,本 PR 单独推进到可替换旧客户端为止;旧 SwiftUI / Tauri 客户端和仓库内旧 Core 已在本分支删除。
已有(无头测试覆盖,原生窗口验收待做):
output_page按游标分页(第二十轮)。environment 与 Maven 专属工具按契约不在本客户端发布。workbench/pagehost.go。lithe-mcp辅助程序由 Core 检出构建后以lithe_bundled_helper标签嵌入客户端二进制,运行时原子安装到应用数据目录;安装包不新增可执行文件、不被运行时写入。toolExposure与 validate 使用同一份 11 工具列表;未发布的工具返回NOT_SUPPORTED。执行状态、错误码、ID 过期规则与输出游标按契约(第二十轮)。验证:最近一次(2026-11-12,第二十四轮,Core
d797244)macOS 本机desktop-go.sh vet ./internal/... ./cmd/...与全量desktop-go.sh test ./internal/... ./cmd/... -count=1(51 包)通过;i18n 三项、功能矩阵 255 项、Agent Notes、运行时 bundle 只读、测试稳定性检查通过;--no-sign打包实测成功。Linux Draft CI。Windows 在 Lithe-dev 上按阶段收尾时全量复验。最近验证(2026-11-10,Corede7a79ec):全量desktop-go.sh test -count=1 -p 4 ./...47 包通过;调试线程/求值监视、单步/指令级单步/只读内存、启动前保存、语义高亮开关、LSP 日志筛选/停止/重启、光标历史、Markdown 链接的端到端测试通过(cb963389a、06f27375d、bb8a32102、94476f3d7、190c8252e、027a093eb)。交接(2026-11-11 夜,HEAD 见分支最新提交)
阶段:第十轮已删除 Agent 对话;第九轮按旧客户端补齐的右键菜单已提交(盘点见第九轮小节)。历史改写 UI 已在第八轮末提交。之后依次:真缺口(IDE 设置导入、SVN/插件 VCS provider、滚动条两项;HTML/SVG/媒体/PDF 预览暂缓(依赖 webview))→ 测试(workbench 的 31 个 Agent 失败用例随 Agent 对话删除,#1827 关闭;Windows 13 个)→ 矩阵 → GUI 验收。
本机工作树(Mac):
/Users/yaoyao/Dev/OpenRes/Lithe-IDEA:主工作树,直接在feature/1794-viva-workbench-shell上提交;推送前 fetch 并变基,只快进。~/Dev/OpenRes/Lithe-core-rust-gaps:Core 克隆,提 Lithe-core-rust PR,合并后改PINNED_CORE_REVISION。踩过的坑:
pgrep -fl "cargo|rustc"为空。desktop/go.mod的 Viva 版本:先 PR 并--admin合并到 Lithe-IDEA/viva,再执行GOPROXY=direct GOPRIVATE=github.com/Lithe-IDEA go mod tidy。偶发 SSL 错误,重试即可。i18n-pending-*.json,i18n.Shared()在导入前返回空串。导入后跑 generate 和三项门禁。ui.Select等控件按指针绑定状态,必须用持久字段,不能用局部变量。WindowsLockFileEx会挡住第二个句柄的读取。第二轮车道(2026-11-10 已合并并推送)
.git元数据监听。未做:行历史、本地变更列表、多仓库分组、Rebase 计划编辑、Diff 搜索/忽略空白。supportsSteppingGranularity时按 instruction 粒度单步;新增只读内存页,经 CorereadMemory读取 256 字节并展示偏移/十六进制/ASCII 与不可读字节数。de7a79ec。第三轮(2026-11-11)
fontprefs、settingswindow/fonts_view.go、workbench/fonts.go):字体以“组”保存,每个位置恰好属于一组,默认一组覆盖全部位置;可以做到“终端 A 字体、其他位置 B 字体”。字体列表在后台读取已安装等宽字体,未安装的字体标“未安装”,空字体名为系统等宽字体。打开页面不写文件,只在用户修改时写回应用数据目录的设置文件;恢复默认值清空保存的字体列表。editorview/font.go)与终端(termview/font.go)按各自字体绘制:字号、行高(字符格高 × 行间距,取整像素)、连字;终端行缓存以连字为键。运行输出与 Git 控制台使用运行输出字体,暂不绘制连字。-c …展开/收起;按字符宽度换行与截断(宽字符不被截半),Tab 按 8 列制表位展开。Changed()。aiGeneration.customInstructions),生成提交信息时去掉首尾空白后作为 CoreAICommitOptions.CustomInstructions传入;设置 > AI 生成卡片也能编辑同一份提示词,两处互相同步,打开页面不写入;文本输入在当次绘制内保存(Viva 的After只在点击类事件后运行,键入时不会触发)。Changed()/Clicked()或页面结束时写回取值,原代码在声明后立即比较局部变量,永远看不到点击;现改为先询问Changed()再读取。editor-font-familymacOS/Windows 更新为 partial / pending,缺口:找不到字体时回退系统等宽字体而非内置字体、最小字号 6 pt(旧客户端 8)、无缺字提示、运行输出不绘制连字。已知小问题:总览里每个位置的“单独设置”按钮无障碍名称相同,暂未区分。(第二十四轮去掉了这些按钮,总览改为按位置名称命名的勾选框)第四轮(2026-11-11)C05 插件工具窗口
plugins.web.open/close/resource/document/request/reply/event。页面能读哪些包文件、文档最前面注入 CSP meta 与window.lithe桥接脚本、每条桥接请求的参数校验,以及回复、进度和主题事件的封装都在 Core;调用 ID 不可复用、最多 16 个调用、一次一个对话框也由 Core 计数。.lithe-host/为保留路径(契约 README 已注明)。已合并为fd9a0d3d,桌面端锁定到该提交;本仓库shared/contracts同步了plugins.web.*与.lithe-host/。desktop/internal/pluginweb:页面宿主。按 Core 给的路径段逐级Lstat读包文件,不跟随符号链接,并限制大小;执行 Core 交回的动作(状态、functions.list/invoke/cancel与进度、文件对话框、workspace.openFile);页面关闭时取消它的全部调用;离开插件源的导航送回入口。ToolWindows列出已启用插件的工具窗口;页面调用插件后端时只收到本调用的requestProgress;页面状态按窗口和工作区存放在<插件根>/.state/<plugin>/pages/…,原子写入。app.WebHost加NativeView显示,引擎就绪前显示“正在打开…”,打不开时说明原因;一帧没有声明某个页面就关闭它(隐藏、移动、关项目、停用或更新插件都走这条路)。对话框标题写明插件名。ui {1,2},带工具窗口的插件可以安装了。staleReference拒绝,面板不再把它当作失败显示(新的停止会重新请求)。TestDebugMemoryReadsWithoutComputedAddresses此前约 1/4 失败,现连续 8 次通过。plugin-web-tool-windows、declarative-plugin-contract,Agent Note、资源复用清单与docs/ci-builds.md已同步。第五轮(2026-11-11)Diff 标签页改为 IDEA 式双编辑器(
0932e1c52)GitDiffRequest.WholeFile以 Core 的FULL_FILE_CONTEXT_LINES作为contextLines读取整文件,Core 在该值下把 Git 的区块间上下文固定为 0;两侧面板由workbench/diffpanes.go从 Core 的区块构建(行文本、行号标签、改动标记、左右片段对应)。diffdecor.go):SetLineHighlights(整行着色或行间细线)、SetLineLabels(以标签替换行号并按标签宽度调整行号区)、CenterLine、LineTop/LineAt/LineHeight、ScrollOffset/SetScrollOffset、BindWithoutMinimap、HideVerticalBar、ShowContent;LineAnnotation增加Icon与Rule。绘制路径仍为 0 allocs(TestRepaintWithHighlightsAndLabelsAllocatesNothing)。finishCloseProject调用closeDiffs)。columns-2(并排按钮)。git-diff-review补充证据与说明,状态仍为 partial / pending。第六轮(2026-11-11)Viva 改由 Lithe-IDEA/viva 维护,删除已不需要的绕过代码
fb52d5482、5cc34c106): Viva 的问题在 Lithe-IDEA/viva 修,合进 fork main 后改replace,同一个修复分支向 vivaui/viva 提 PR;发版只认go.mod固定的 commit,fork main 同步上游只用 merge。规则写在 Agent Note.agents/notes/implemented/process/2026-11-11-viva-fork-maintenance-and-commit-pin.md,AGENTS.md、develop-lithe Skill 和桌面入门文档同步更新。go.mod解析出的 Viva 源码目录构建命令行工具,因为go run/install …@<版本>会忽略replace。两个图标脚本重新生成的输出与已提交文件逐字节一致。ed0b89b(上游b680a1c+ [Feature] Viva List 应用 ScrollTo/ScrollToEnd 的那一帧显示旧偏移:上游修复后移除 Lithe Diff 标签页的重绘绕过 #1820 修复),之后合并上游 v0.6.0(只多了docs/releases/0.6.0.md),改为7edac95。[Feature] Viva List 应用 ScrollTo/ScrollToEnd 的那一帧显示旧偏移:上游修复后移除 Lithe Diff 标签页的重绘绕过 #1820 修复和上游 [Bug] Windows 导入配置时:无法扫描已安装的编辑器 #216 在ui/list.go冲突,已经合并上游 main 解决:保留 [Bug] Windows 导入配置时:无法扫描已安装的编辑器 #216 的多帧收敛,只叠加“移动了偏移就写回区域节点”。我们的回归测试TestListScrollToARow在纯上游代码上失败,在合并后的代码上通过;BenchmarkList100k上游约 11.0 µs/op,合并后约 11.2 µs/op,都是 0 allocs。e9afae33e、b42f28e89):internal/monogrid。Git 日志详情的标题、引用、作者行改用ui.Wrap(...).Mono()和ui.Flow,不再手工断行。Git 控制台的片段不再自己算宽度。日志窗口的mono()不再补宽,说明文字用ui.Wrap(...).Mono(),JSON 详情用ui.Scroll(...).Sideways().Scrollbars()横向滚动,和 macOS 一致,不再按列折行。删除对应的手工换行测试,新增TestLogCommitDetailsWrapMonospacedSubject、TestDetailJSONScrollsSidewaysInsteadOfWrapping。c.After推迟(依赖 fix(ui): carry event-pass focus requests and close key routing gaps vivaui/viva#217)。两个测试都在快捷键之后立即检查焦点。.Disabled(...)不起作用(用户可见:忙碌时仍可输入,共 10 处)、只读输入框手画、Tree 不处理横向滚轮、List 把纵向滑动的横向分量拿去横向滚动、Splitter 方向键和终端/编辑器组合键要走窗口OnKey。after-diffview→after-viva-cc1c87d,M4,--count 6): 112 项中 109 项在预算内,超预算的仍是既有 3 项SyntaxFullPass(go/java/markdown 100KiB,本次 −1.0%~−1.8%),不是本次引入。分配变化只有 ±1~2 次。ViewPaint/wrap/100KiB首轮 +17.3%,单独-count 5复测为 43.8~45.0 µs,对比基线 42.5 µs,约 +3%,按噪声记录。之后固定版本从cc1c87d改到7edac95,换了上游基线,编辑器代码没有改动。desktop-go.sh test -count=1 ./...通过;desktop-go.sh vet ./...、viva vet ./...0 条;i18n 两项、功能矩阵 255 项、Agent Notes 233 篇、运行时 bundle 只读检查通过。第七轮(2026-11-11,先写代码阶段:只保证 vet 通过,测试/文档/矩阵/i18n/CI 集中收尾)
合并方:
update:签名源检查、下载校验、安装,设置 › 更新)、窗口标题跟随项目与文件(VivaSetTitle)、内存监控(语言服务器与插件服务分项、明细弹层)、编辑器代码折叠(editorview 行映射隐藏行;语言服务器 foldingRanges 优先,否则按缩进;命令与快捷键)breakpoints;插件编辑器动作按第 2 版解码并声明hostOptions.editor(core.EditorHost)车道(均已合入 integrate 并推送):
第七轮续(2026-11-11 下午,均已合入 integrate 并推送,HEAD
a26073264之后):keymap.modifierGestureStep);输入法组字让出宽度(editor-macos-ime-presentation);通知中心按类型着色与欢迎页铃铛;终端原生配色(WCAG 门控)与 Nerd Font 优先;HTML/SVG 在浏览器中打开;Core 固定到 a783ed9(Lithe-core-rust#11:documentLink、workspace/symbol、GitHub checks 与评审线程、disconnectterminateDebuggee):w :q :wq :x :{n} :s :%s、标记、具名寄存器与"+/"*、状态栏模式项、设置开关);问题面板预览分栏、筛选与分组;文档链接(插件)悬停与点击;补全多来源合并ui.commands(查找操作 + 快捷键目录可改绑)第七轮续二(2026-11-11 晚,均已合入 integrate 并推送,HEAD
a26073264之后续):setPinned持有(删除 Go 端document.pinned);重开项目恢复编辑器会话(分组、分屏比例、选中、焦点、光标、固定)head_sha)、lithe 0.1.14 #13(execution.planLaunchCommand),桌面固定到fbe848a;Java 长 classpath 改由 Core 规划,删掉 Go 端重复规则,Windows 按系统代码页编码参数文件Config.OnFocusLost)与键盘离开编辑器时立即保存;Build 窗口依赖树(Corebuild.dependencyPlan/decodeDependencies);插件行首图标车道菜单在图标下方弹出(ui: MenuAt opens a menu at a point of the window Lithe-IDEA/Lithe-viva#3ui.MenuAt);搜索排除目录经 Coreworkspace.configureIndexing生效(打开安装、规则变更刷新、关闭释放租约),项目树“取消排除”与根节点“自动排除 Git 忽略目录”开关leftChanges/rightChanges(Go 已解码,Diff 视图尚未绘制)build.resolveStoredOptions/editStoredOption,团队文档.lithe/build/options.json只读、本地文档存应用数据目录)与构建窗口“构建选项”对话框;IDE APIlithe_build_configure已分发;Vim Visual Block(Ctrl+V,含 I/A/c/d/y/r/p/P/o/O)收尾阶段待办(新增):
ide_api_dispatch_test.go第 21 行“不分发 build_configure”的断言改为已分发;shortcuts 默认键测试纳入 5 个多光标动作;测试夹具设DisableAutoSave;fake kernel 补indexingKernel、buildDependencyKernel等类型断言接口Diff 视图按(leftChanges/rightChanges画词内高亮6256f1fa1);历史改写 UI(进行中)(撤销/删除/压扁提交、编辑提交信息:Core 已有 historyRewritePreview → 审阅 → 带 expectedState 写入);Vim 块操作的.重复cherry-pick / revert / reset 的请求字段契约(Lithe-core-rust#15,bdd12452a固定并加 Go 封装);launch.json 导入无 Core 命令shared/contracts/vcs-provider-v1.md,Go 侧未接)i18n-pending-{me,git,ide,ai}.json(实际 612 条)到shared/i18n/,跑 generate 与三项门禁(cabbf4f5c):命令行、H/M/L 折行落点)、输入法组字、双击 Shift 与 Tab 切换标签页、Search Everywhere 预览、新增状态栏项(旧布局可能需重置)UpdateFeedURL/UpdatePublicKeysignoreAllWhitespace;PR checks/评审线程、documentLink、workspace/symbol、disconnect 策略已在 [Feature] 适配其他语言系 尤其是前端部分 #11 合入)java_feature_version_from_release(Cored797244中已一致);lithe-plugin-docs 已退役,契约只在 Coreshared/plugins/,不再需要同步第八轮(2026-11-11 夜,收尾优先级 1:代码缺口)
6256f1fa1Diff 视图按 Core [Feature]windows后期适配建议,运行多服务选项 #14 的leftChanges/rightChanges画词内高亮:editorview 新增InlineHighlight/SetInlineHighlights(设置时把 UTF-16 列换算成单元格,绘制时按行二分查找,重绘零分配),画在行底色之上、选区和文字之下;并排视图用 modified 色,统一视图按删除/新增色;性能基线见下文。27831d9f3修 Log 列表点击提交后右侧详情不显示:“从此处变基”菜单给每行另设的点击目标收走了左键,列表选不上提交;改为把右键菜单挂在列表行自身上(与暂存、调试列表一致),TestLogCommitListSelectsWithTheKeyboard覆盖。894bf60da窗口标题变化后红绿灯按钮保持居中(darwin: keep the traffic lights centered when the title changes Lithe-IDEA/Lithe-viva#5)。bdd12452aCore 固定到1274b3f(后续48c6991f9升到d797244,含 [Feature] 希望尽快推出 Windows 版,另外支持一下 keymap 自定义 #16 控制台折叠与 feat(database): add integrated database workspace #17 契约单一基线;Lithe-core-rust#15:cherry-pick、revert、reset 写入请求与git.operationState/operationControl/integrationPreflight/historyActionCapabilities),Go 端core/git_history.go封装历史改写预览与写入。cabbf4f5c导入第七轮待办词条 612 条,删除i18n-pending-*.json;generate-i18n.mjs --check、verify-app-language-localization.mjs、test-i18n.mjs通过。150db9b9aViva 固定到 fork main7850516([Feature] 现在是支持的Spring系,希望增加支持quarkus系 #6MenuItems.Beside())。1e5a9accd分支弹窗参照旧版重做:行菜单从行右侧展开(放不下才翻到左侧);顶部操作补齐 Update Current Branch、Commit…、Push…、New Branch、Checkout Tag or Revision、New Tag,搜索时加 Fetch;行菜单为 New Branch from、Compare with Working Tree、Compare with Current、Checkout、Update、Push…、Rename、Delete;行高压到 24pt,Local/Remote 按/折叠成文件夹(默认收起)。修根因:同步、比较、推送原先作用于项目仓库,现在作用于弹窗选中的仓库(嵌套仓库不再误推项目仓库)。测试加popupHit(取最上层图层的控件),避免同名控件命中背后窗口。第九轮(2026-11-11 夜,按旧客户端补齐右键菜单与零散修复)
逐个对照旧 SwiftUI 客户端的
litheContextMenu,把已有功能的右键菜单接上;菜单项都调用对应按钮的同一个动作,按钮被禁用的状态下菜单项同样禁用。c73fd2fdf合并 diff 的竖条与缩略条按行着色,删除行改红色;切换提交时取消旧的读取。b06fd169eGit 控制台把内部读取命令淡化并整段折叠,可一键隐藏(Core [Feature] 希望尽快推出 Windows 版,另外支持一下 keymap 自定义 #16)。4701b1d3d日志提交右键菜单补齐复制哈希、标签、拣选、还原、重置与历史改写,并显示进行中的合并/拣选/还原。d1d442fab日志引用面板的分支右键菜单补齐比较、签出并变基、合并、变基、拉取、跟踪分支与复制分支名。d0a0e3811提交窗口变更行、终端、标签页与项目树右键菜单补齐旧版操作。fb1711cd0双击 Shift 打开全局搜索;输出面板逐行右键菜单;关闭终端时等待 shell 退出。96c6d89cd“在当前窗口打开”项目改为项目标签,与旧版一致。f9ab844ca全局搜索滚动到底自动翻页,不再跳回首行。a9f2d6fb6调试面板补齐右键菜单;插件原生树面板右键不再崩溃。866b9bc17“在文件中查找”结果行右键菜单:打开、在访达中显示、复制路径与相对路径。5ecb713e7工作树列表行右键菜单:打开、在新窗口打开、在访达中显示、复制路径、锁定、移除、清理失效记录。484c128d4快捷键设置行与反汇编指令行右键菜单;从菜单打开反汇编不再空白。16b305e18构建工具窗口右键菜单:任务运行;目标按适用的运行方式运行;项目打开构建文件、重新加载模型;依赖树重新加载。修根因:构建根不在工作区根时,打开构建文件(含原有双击)按契约以构建根解析项目路径,不再找错目录。0af74618f侧边栏按钮菜单加“前移/后移”(同一区域内);工具窗口标题栏右键可隐藏该窗口(旧版 Problems 标题栏);“全部替换”预览的文件行右键菜单(打开第一处改动、在访达中显示、复制路径与相对路径;预览是模态窗口,打开文件前先关闭预览)。修测试:clangd 端到端用例的测试清单补上契约归 0 后必填的requires(此前 8 个用例被误当成环境超时);切换项目用例改为先关闭再打开(已有项目时再打开会新建项目标签)。9dc094ee5断点右键菜单加启用/禁用;禁用的断点在列表中淡化,保留行号与选项,Core 不发给适配器;随编辑重定位时保留启用状态。e2737bf7b编辑器行号区显示断点(禁用为空心、条件、日志点),点击行号切换断点,暂停时着色当前执行行;断点列表改为调试窗口分页,修复暂停后调用栈被挤成零高度。editorview 改动前后基线(同一台 M4,scripts/desktop/perf/editor-bench.sh,.artifacts/editor-perf/bp-before.*→bp-after.*):28 项全部在预算内,无新增超预算;最大变化Paint/java/100KiB+6.3%,Paint/gutter±0.1%,分配数全部不变。行号区断点:改动后基线(vs 改动前)
This report never fails the build; overruns are findings to fix or to justify in the PR.
盘点结论(旧版菜单所在功能在新版整体缺失,菜单随功能补,已记入下方“功能缺口”):
Shelf(搁置变更)(第十三轮补齐)。调试:线程暂停/继续、监视表达式行内编辑(第十一轮补齐;行断点启用/停用已在9dc094ee5补齐)。构建窗口的测试:Run Tests、按项目范围测试、Discover Tests(第十二轮补齐);依赖侧栏的“从依赖树排除”。第十轮(2026-11-12)删除 Agent 对话
用户决定 Viva 桌面端不做 Agent 对话(
51ee91dcd):desktop/internal/core/agent*.go、mcp.go,internal/agentbrand、internal/mcpconfig。97 个文件,约 1.7 万行。workbench/ai_provider.go,只调 Core 的ai.configuration.sources/parse;生成选项移到设置 › AI › 生成,设置文件字段aiGeneration不变。AI 分组现为“生成 → IDE 连接”。shared/i18n删除只给桌面端 Agent 用的 474 条,与旧客户端共享的 490 条只去掉desktop平台。agent-*/mcp-*行改为missing,docs/viva-migration.md新增“放弃:Agent 对话”表。implemented/feature/2026-11-12-viva-agent-conversation-removed.md;Viva Agent 桥与 Markdown 回复两篇归档;四篇子进程与 ACP 笔记去掉已删路径。TestCoreChildProcessesKeepGoSignalStack改用 Go 与 Core 的git status子进程验证 SIGCHLD 仍带SA_ONSTACK;工具窗口拖放测试改用 Markdown 预览代替助手窗口(第二十三轮起改用“通知”窗口)。[Feature] 桌面端 Agent 面板 31 个用例在欢迎选择页上线后过时 #1827 的 31 个 Agent 失败用例随代码删除。shared/fixtures/agent、shared/fixtures/mcp,是否删除待用户决定。a4eb41350修运行时 bundle 只读检查(随包字体f30c102d3与新窗口打开项目96c6d89cd各自调用os.Executable,检查失败):安装包位置只在新增的internal/installedpackage查找(Executable只用于启动另一个客户端,ResourceFolder只读返回 bundle 内固定资源目录),检查脚本只放行该包,并在该包出现写文件、exec、syscall 时失败;测试确认读取并注册随包字体前后 bundle 文件清单与哈希不变。desktop-go.sh test -count=1 -p 4 ./...48 包通过,vet0 条;i18n 两项、功能矩阵 255 项、Agent Notes 232 篇、运行时 bundle 只读检查通过。第十一轮(2026-11-12)调试单线程继续与监视行内编辑
supportsSingleThreadExecutionRequests时经 Coredebug.execute(singleThread: true)单独继续一个线程。Go 绑定原来漏了singleThread字段,新增ExecuteDebugThread;Core 无改动。continued事件在会话仍暂停时只清掉该线程:选择器标“(运行中)”,该线程不再显示栈、变量和监视值;其他仍停着的线程照常切换查看,单步按钮在当前暂停线程被单独继续后禁用。整体继续或下一次停止清空单线程状态。desktop.debug.threadRunning;native.pauseThread、native.resumeThread、native.editWatch加入 desktop 平台。TestDebugThreadResumesAloneAndWatchEditsInPlace(fixture 适配器支持单线程请求,走真实右键菜单、双击、Enter/Esc);调试相关 workbench/core/i18n 测试、vet、i18n 三项检查、功能矩阵校验通过。第十二轮(2026-11-12)构建窗口的测试入口(
5e768983e)project测试范围时出现,按该项目运行(Corebuild.testPlan的 project 范围)。target范围、且目标带有声明的targetTags之一时出现(未声明标签时所有目标都可以);连同所属项目一起交给 Core。窗口只隐藏 Core 会拒绝的入口,规则仍由 Core 判定。discovery的构建系统在构建树末尾显示“已发现的测试”分组。只在用户点“发现测试”或右键“刷新已发现的测试”时运行(可能触发编译):Corebuild.testDiscoveryPlan规划,插件 provider 回答lithe/build/discoverTests,Corebuild.decodeTestDiscovery校验并限长。每个测试双击或点行内按钮单独运行,原样带回 suite/case/项目/目标选择器;行按当前选中的项目筛选。core.PlanBuildTestDiscovery、DecodeBuildTestDiscovery,测试声明读取targetTags;Core 无改动。新文案desktop.build.testDiscoveryFailed;native.runTests、native.runAllTests、native.discoverTests、native.discoveredTests、native.discovering、native.noTestsDiscovered、native.refreshDiscoveredTests加入 desktop 平台。TestBuildWindowRunsProjectTargetAndDiscoveredTests(fixture provider 两个项目、带标签和不带标签的目标;走真实右键菜单、点击、双击,逐次检查 provider 收到的选择器,最后保存源码确认清单撤销);构建、测试窗口、文档保存相关 workbench/core/pluginservice/i18n 测试、vet、i18n 三项检查、功能矩阵 255 项通过;全量desktop-go.sh test ./internal/...49 包通过,运行时 bundle 只读检查通过。第十三轮(2026-11-12)Commit 工具窗口的 Shelf 页签(
b6cec1d0d)git.shelf的capture读取暂存区与工作区(含未跟踪文件)两层补丁;客户端先写入记录,再按plan(clean)的顺序逐层clean。有冲突时 Core 返回SHELF_CONFLICTS,层内容变化返回SHELF_CHANGED,失败时记录保留,提示“仓库已发生变化。搁置记录已保留…”。没有改动时提示“没有可搁置的改动”。plan(restore)逐层restore,全部成功才删除记录。失败时记录保留,可以重试,Core 会识别前一次已应用的层。删除只移除记录,不动工作区,需要确认。git.saved.unsaved,与旧 Windows 客户端一致)。Shelves/<仓库根路径 sha256 前 8 字节>/<随机 id>.json,格式版本 1,原子写入。不写仓库、不写安装包。读取时跳过其他格式、id 与文件名不符和无法解码的文件,并记入日志。git.parsePatch解析两层补丁,文件树按“暂存区”“工作区”分层(层标题吸顶),再按目录分组。双击文件打开只读 Diff 标签页:暂存层为 HEAD ↔ 暂存区版本,工作层为暂存区版本 ↔ 工作区。workbench/saved_files.go(Stash 一层无标题,Shelf 两层),Diff 标签页的stashSource改为通用savedSource(左右标签由来源给出);删除与projectRelative重复的projectRelativePath。core.GitShelfCapture/Plan/Clean/Restore、GitParsePatch。Core 无改动。git.saved.tab/shelves/staged/restore/drop/changed/conflicts/noChanges/unsaved、native.shelveChanges/noShelves/lldFileS/couldNotLoadSavedChanges/thisRemovesTheSavedPatchFromLitheAndCannotBeUndone加入 desktop 平台。TestShelfTabShelvesShowsRestoresAndDropsShelves:真实 Git,覆盖暂存新文件、工作区修改和未跟踪文件。依次检查:搁置后工作区干净;记录在客户端目录;两层文件与两种 Diff 标签;有未保存文件时拒绝恢复;冲突时恢复失败、记录保留;重试后三类改动全部还原、记录删除;删除需要确认且不动工作区。TestReadShelvesSkipsForeignFiles、TestGitActionsMenuShowsTheShelfTab。desktop-go.sh test -count=1 ./...50 个包通过,vet0 条;i18n 三项检查、功能矩阵 255 项(git-rebase-stash补证据)、运行时 bundle 只读检查通过。第十四轮(2026-11-12)运行配置浏览列表(
9cbf595d4)buildOperation记录所运行的配置 id)。Enter 或双击运行;组行 Enter/双击折叠展开。run-configuration-pins.json(按项目根路径存排序后的 id),首次解析出配置后读取;写入失败保留原状态并提示。不写项目、不写安装包。配置暂时消失(模型重载中)时置顶保留。native.allConfigurations/pinned/services/applications/tasks/groups/pinConfiguration/unpinConfiguration/editConfiguration/noConfigurationsInThisScope/runConfigurations/lld.variant2/collapseSection/expandSection/stopRun.variant2/running加入 desktop 平台;删除不再使用的desktop.runConfig.label/edit。TestRunConfigurationListScopesGroupsPinsAndRuns——范围与数量、分组与排序、右键置顶写入客户端存储且不写项目、重新读取后置顶范围只剩该配置、折叠/展开、双击经插件发出该运行请求、运行中行显示停止并能停止、取消置顶后存储清空并显示空范围提示。ListState.Selection已支持多选)、服务地址提示(端口规则应先进 Core)。desktop-go.sh test -count=1 ./...50 个包通过,vet0 条;i18n 三项检查(范围标题改为字面量词条)、功能矩阵 255 项(run-discovery补证据,仍为 partial)、运行时 bundle 只读检查通过。第十五轮(2026-11-12)插件 VCS Provider 工具窗口
vcsProviders。已启用插件的每个 VCS Provider 各有一个底部工具窗口,标题取 Provider 自报名称,使用通用分支图标;插件启用、停用或换包时窗口随目录更新。工作区根由 Corevcs.detectRoots识别(嵌套、歧义目录由 Core 判断),用户为歧义目录选定的 VCS 存客户端数据目录vcs-root-mappings.json,不写项目。PlanPluginVcsProvider的计划启动 Provider;buildprovider改为同时承载构建和 VCS 两种角色,从 Core 的vcsProvider事件记录协商到的 VCS 和能力。协商不到或 VCS 不匹配时关闭会话并提示。每个请求由 Corelsp.vcsRequest生成,回复由vcs.decodeReply校验后才用;Provider 错误按 Core 保留的错误码显示(ProviderError)。push能力的 VCS 提示提交会直接进入仓库。工具栏和右键菜单按协商能力显示:刷新、显示差异、回滚(确认对话框列出路径)、更新、标记为已解决、清理、重新识别。“历史”页分页加载修订,列表与修订详情之间可拖动。baseContent取基线,用 Core 已有的diff.compareTexts和磁盘内容比较(新增core.CompareTexts封装),打开只读 Diff 标签页;Provider 标为二进制或磁盘内容不是 UTF-8 文本时显示为二进制,基线为 null(新增文件)时按空文本比较。closing),迟到的启动由启动方自己关闭;构建会话加detached计数,detach 之前开始的启动不再挂到新会话上。c.After只在点击/指针事件的绘制中执行,普通绘制里登记的回调会被丢掉。所以窗口的识别、状态和历史改在绘制时直接触发,与 Run 窗口的loadBuildSystems做法一致。desktop.vcs.commitDirectly,其余复用已有native.*词条(加入 desktop 平台)。TestVcsProviderWindowListsCommitsAndRollsBack用一个按契约应答的假 Provider(测试进程自身)走完识别、分区与标题、双击只读 Diff(+1/-0)、右键回滚确认与请求参数、勾选提交与提交信息、提交后显示新修订、标记解决后冲突分区消失、历史页;TestBuildRuntimeDetachKeepsTheRuntimeOpen覆盖 detach 计数。fileOperations(项目树添加/移动/删除交给 Provider)、项目树状态着色、vcs.ownerOf、lithe/vcs/execution控制台输出、冲突另一方显示、历史条目 Diff、authenticate;真实 Subversion 插件(lithe-plugin-svn)验收。desktop-go.sh test -count=1 ./...50 个包通过,vet0 条;i18n 三项检查、功能矩阵 255 项(vcs-subversion-and-plugin-providers改为 partial/pending)、运行时 bundle 只读、测试稳定性检查通过。第十六轮(2026-11-12)插件 CodeLens 路由、工具启动、打包字体恢复、矩阵复核(
517900b79、a790c8bae、fc7e22c9a)core.EditorHost.ProviderTypes缺codeLens,Core 一直拒绝插件的 CodeLens 注册;现已声明该类型。pluginservice/hostproviders.go改为按providerFunctionFields一张表路由,去掉六段几乎相同的分支。新增core/editor_providers_test.go(Core 接受全部六种类型,仍拒绝foldingRange)和pluginservice/hostproviders_routes_test.go(每种类型都落到插件注册的函数上)。{kind:"tool"}启动:pluginbackend.ToolResolver改为接收工作目录,返回ToolExecutable(程序路径加上所选工具声明的环境,如工具目录与 PATH)。工作台用resolveBackendTool解析,走与 Run 相同的工具链层级(resolveRunTool)。环境变量按“工具 < 计划 < 请求”覆盖。测试TestStartResolvesAToolThroughTheHostToolchain。f1e8d8139删除,发行包实际用的是系统字体):desktop/internal/bundledfont/fonts,与 preview 上的 git blob 完全相同:Inter 4.1 的 18 个 OTF、JetBrains Mono 2.304 的 16 个字型、JetBrainsMono Nerd Font Mono 的 4 个字型,以及许可文件。NOTICE.txt写明来源和每个字型的 SHA-256。lithe_bundled_fonts构建标签经 go:embed 编进可执行文件(package-desktop.sh传入该标签)。运行时不读写 bundle 的 Resources,因此删除了已无用的installedpackage.ResourceFolder。app.RegisterFont按进程范围注册(暂存副本在用户缓存目录viva/fonts)。界面在首次绘制前切换为 Inter,编辑器和运行输出默认 JetBrains Mono。开发与测试构建不带字体,用系统字体。terminalNerdFonts顺序取第一个可用的 Nerd Font。已安装的 MesloLGS 优先,其次是打包的 JetBrainsMono Nerd Font Mono,再其次其他已装的 Nerd Font,都没有时用打包的 JetBrains Mono。之前打包的 Nerd Font 从未参与选择(fonts_test.go)。desktop-go.sh test -tags lithe_bundled_fonts ./internal/bundledfont/):嵌入文件与仓库文件逐字节一致;用真实 CoreText 注册得到三个字体族;Nerd Font 出现在等宽字体列表里。worktree-resources.json的bundled-ui-fonts改为新位置(并加了测试断言),docs/ci-builds.md的字体章节和打包字体 Agent Note(新增“Viva 客户端:字体编译进可执行文件”一节)已同步。.gitattributes把字体目录标为-text。test-runtime-bundle-immutability.mjs)在a4eb41350加入 installedpackage 检查时没有同步,有两例一直失败。现在夹具补上 installedpackage,并新增一例覆盖“installedpackage 必须只读且必须存在”。embedded-viewers。desktop-go.sh test -count=1 ./internal/... ./cmd/...49 个包通过。vet、Agent Notes 232 条、运行时 bundle 只读检查及其 Node 测试、资源复用测试。第十七轮(2026-11-12)“打开所选文件”可改绑,补 F4 测试(
ffe9701ea)shortcuts.OpenSelected(workspace.openSelected),默认 F4,归在“项目”分组,标题沿用共享词条keybindings.commands.file.openSelected.title(这一条的 platforms 加上 desktop)。设置的快捷键页可以改绑或禁用它,和其他动作一样做冲突检查。elementShortcut把用户的有效按键声明在自己的元素上(root.go)。原来写死的Shortcut(0, "f4")已删除。689efc520已实现,此前没有测试):TestProjectSearchF4OpensTheSelectedMatchAndKeepsItsPlace覆盖五点:listRowScope只登记 List 的行范围,没有 Tree 的,所以 Tree 的某一行有焦点时Box.Shortcut不触发。TestTreeShortcutActsWhileARowHasFocus。去掉修复时该测试失败;Viva 除cmd/viva外全部测试通过。TestProjectTreeOpenSelectedFollowsTheKeymap暂时t.Skip,等固定版本包含 viva#9 后去掉。用7850516加上这个修复在本地跑过,该测试与TestProjectTree*全部通过。已记在 [Feature] 在 Lithe-IDEA/viva 补齐输入框禁用/只读、Tree 横向滚轮与行内 label、Splitter 按键路由,移除 Lithe 的对应绕过代码 #1821 第 8 项。file-open-selected的说明、证据和验证步骤已按现状改写,仍为“部分”(项目树等 viva#9;查询框 F4 未做)。docs/viva-migration.md对应行已同步。desktop-go.sh vet ./internal/... ./cmd/...通过;全量./internal/... ./cmd/...49 包通过、无失败;i18n 三项检查(生成、语言、--check)与功能矩阵生成/校验通过第十八轮(2026-11-12)本地历史 Diff;快照改存客户端数据目录(
019d54dfe)savedSource承载 Corediff.compareTexts的结果,可切换并排/统一视图、查找、折叠。localHistory.compareWithCurrent、compareWithPrevious、noChangesToCompare和native.currentVersion,只给它们加上 desktop 平台。<用户配置目录>/Lithe/LocalHistory。<客户端数据目录>/LocalHistory/<项目路径哈希>,与 Shelf 相同。测试用临时 store,因此自动隔离。Viva 预发布版之前记下的历史不迁移(只是预发布数据)。TestLocalHistoryComparesASnapshotWithThePreviousOneAndTheCurrentText,覆盖五点:history-snapshots的说明、证据和验证步骤按现状改写,仍为“部分”。未迁移:本地历史设置(忽略规则、容量、清空)、全项目时间线、手动标记条目。desktop-go.sh vet ./internal/... ./cmd/...通过;i18n 三项检查(generate、verify-app-language-localization、--check)通过;功能矩阵校验通过;workbench、i18n两个包全量测试通过(129s);变异检查:把“与当前比较”改成读磁盘文件后新测试失败,恢复后通过第十九轮(2026-11-12)网络设置页“测试连接”(
3b7665e51)network.proxyPolicy解析,密码规则与保存时相同:新输入的密码随草稿的端点;密码框没改动时取钥匙串里的已存密码,由 Core 校验它属于同一端点和账号;点过“清除密码”就不带密码。Core 得出的不是完整的自定义服务器时按“未填完整”处理。http.Transport上发一个 HEAD https://github.com 请求,10 秒内必须结束(含 Core 解析),不跟随重定向。200–399 算成功,显示耗时;其他状态码显示“代理返回了 HTTP …”;没有响应时显示“连接检查失败。”加上原因(不带请求地址)。netproxy.Check(新增):按策略决定每个请求是否走代理,与应用的请求用同一个proxyFor(由Proxy拆出),因此排除列表同样生效。workbench/network.go:新增checkNetwork/networkChecker。applyNetwork、setNetwork和检查共用新的networkProxyRequest、networkIdentity,不再各自拼请求。settingswindow:新增Options.CheckNetwork、NetworkCheck和带锁的检查状态。settings.network.testConnection、testing、connectionSucceeded、checkFailed、enterAddressAndPort、proxyAnsweredWithHTTP,只给它们加上 desktop 平台。netproxy/netproxy_test.go:用本地 HTTP 代理验证请求经代理并带 Basic 凭据、重定向不跟随、不改当前策略;排除的主机直连;代理关闭时只报原因。workbench/network_check_test.go:用真实 Core 验证新输入的密码、本端点的已存密码、换端点后的已存密码(Core 丢弃密码、保留账号)、已清除的密码,以及没有服务器时不发请求。settingswindow/network_view_test.go:页面流程,覆盖进行中的提示、耗时、状态码、失败原因、还原后清除结果、未填完整时不调用检查、非自定义模式不显示按钮。refactor):排除列表的写法解释和匹配只在 Go 的netproxy.Excluded,Core 只去空格,应下沉到 Core。这是旧客户端交给系统网络栈、迁移后落到 Go 的既有债务,本轮不改。network-proxy-settings的说明、证据和验证步骤按现状改写,仍为“部分”。未迁移:代理认证只有 Basic(旧客户端还支持 Digest/NTLM);旧钥匙串app.lithe.desktop.proxy的密码没有可选导入。desktop-go.sh vet ./internal/... ./cmd/...;generate-i18n.mjs、--check、verify-app-language-localization.mjs;平台功能矩阵校验(255 项);netproxy、settingswindow、workbench、i18n四个包完整测试通过;三项反向验证按预期失败,恢复后通过。第二十轮(2026-11-12)IDE API 执行语义按契约收齐(
4f3765616)lithe_operation_output在窗口线程取这次执行的完整输出,交给 CoreideHost.control的output动作(output_page)分页。reset: true并从头读。core.IDEHostOutputPage。OPERATION_BUSY、BUILD_MODEL_NOT_LOADED、OPERATION_NOT_RUNNING、NO_PROJECT、CANCELLED。未知工具返回NOT_SUPPORTED(原为NOT_AVAILABLE)。buildRefusal(INVALID_ARGUMENTS/NOT_FOUND/NOT_READY/NOT_SUPPORTED/BUSY),工具调用原样报这个码,窗口仍只显示原有提示。WORKSPACE_CLOSED,调用超时返回TIMEOUT,Core 分页失败返回OPERATION_FAILED。beginBuildOperation在计划、保存和提供方请求之前登记执行,所以:BUSY。buildOperation.bind),已发出的提供方请求在后台取消,停止后才到的请求或进程直接取消,不再挂到这次执行上。startRunConfiguration)同样先占住窗口再保存。desktop.build.stopping),直到执行结束。run_start/run_restart等执行启动(进程或提供方请求已存在)后再应答,最多等 5 秒。LAUNCH_FAILED和原因。NOT_AVAILABLE;执行未结束时返回BUSY。ide-<build|run>-<epoch>-<n>,epoch 在项目每次打开时随机生成,n 是序号。OPERATION_EXPIRED,从未发出的 ID 返回NOT_FOUND。原来旧 ID 可能指到别的执行。build_configure等 Core 读回后才应答:build.editStoredOption,答复 Core 从改后的文档读回的值和来源(user / default / unset)。原来在写入前就按请求值应答。INVALID_ARGUMENTS,不写入。BUSY。runBuildTask返回它占住的执行,IDE 的执行入口不再从窗口状态里取。ide-api/v1.md有一段仍说 Windows 提供这两组工具,已记入“合入后”。workbench/ide_api_operation_test.go,用真实 Core:BUSY;列表和停止在准备中生效;执行结束为 cancelled,退出码为 null;下一次执行后旧 ID 返回OPERATION_EXPIRED;构建任务不能 restart。build-instance-options的release选项:设置后读回 true / user 并写入本地文档;非法值返回INVALID_ARGUMENTS;设为 null 后来源不再是 user,本地文档被删除;未知选项和未知实例返回NOT_FOUND;对话框打开时返回BUSY。ide_api_dispatch_test.go改写:启动拒绝码表、ID 的当前 / 过期 / 未知规则、状态只结算一次。ide_api_test.go:未知工具和 environment 工具返回NOT_SUPPORTED。ide-api-run-output、ide-mcp-connection、ide-api-maven、ide-api-environment的说明、证据和验证步骤按现状改写,状态不变。desktop-go.sh vet ./internal/... ./cmd/...;i18n 三项;平台功能矩阵校验(255 项);全量desktop-go.sh test ./internal/... ./cmd/... -count=1(50 包)通过;五项反向验证按预期失败,恢复后通过。第二十一轮(2026-11-12)异常退出遗留进程清扫、停止等待时间与强制结束(
5de0940e5)processledger)记录 PID 和启动时间,用来防止 PID 复用。上次留下、现在仍在运行的进程,在窗口打开后交给 Core 的processLifecycle.resolve(startupSweep上下文)。processLifecycle.settle结算。StartupLeftovers和SettleStartupLeftovers加了锁,结算在后台执行。Sweep。resolve探测出来;已建单 [Feature] 停止等待时间的默认值与上下限由 Core 公开,桌面端不再三次探测推导 #1830,让 Core 直接公开。buildprocess.Stop)。原来是直接结束。startupSweep和gracefulStopSeconds,只取能映射的值。buildprocess.StopsGracefully和processledger.Supported控制)。idehelp测试在 Windows 上不再检查 Unix 权限位。documentsUnder测试按平台分隔符构造路径。processledger_unix_test.go(真实子进程):buildprocess/process_unix_test.go:Stop 先请求退出、超时再结束;Kill 立即结束。workbench/startup_sweep_unix_test.go(真实 Core 和真实 sleep 进程):TestStopTimeFollowsCoreAndTheSetting:读到 Core 的规则 {5, 1, 60};设为 12 秒后生效值为 12 秒;设为 1000 秒时被限制为 60 秒;恢复默认后回到 5 秒。process-termination-policy和run-processes-end-with-ide的说明与证据已更新,状态不变。desktop-go.sh vet ./internal/... ./cmd/...;buildprocess、processledger按 Windows 目标交叉 vet;i18n 三项;平台功能矩阵校验(255 项);运行时 bundle 只读检查;测试稳定性静态检查;全量desktop-go.sh test ./internal/... ./cmd/... -count=1(51 包)通过;新增启动清扫测试连跑 3 次通过。第二十二轮(2026-11-12)补齐已实现功能的回归测试;本地历史设置(
d4b766f5d、3dc43e1bc)d4b766f5d)。下面这些功能早已接通,只是缺测试,矩阵说明也过时了:editor-git-gutter-peek、markdown-images-links改为 implemented;git-diff-review、workbench-notifications的说明按现状改写。diff_find.go顺带修了一处判断。history.usage计算。没有打开项目时提示先打开项目。history.clear删除并重新计量。失败时显示原因,可以重试;历史为空时按钮不可点。history.ignorePreview实时检查(200 ms 防抖,过期结果丢弃)。localHistory),每次记录快照都随请求交给 Core(HistoryPolicy)。快照仍在客户端数据目录,不写项目,也不写安装目录。hiddenFilePatterns,按 Core 的默认隐藏规则处理。desktop.settings.localHistory.*);26 条旧 macOS 词条加上 desktop 平台后复用。history-snapshots加了 4 个证据文件和本地历史设置的验证步骤,状态仍为“部分”。还缺两项:全项目时间线、手动标记条目。settingswindow/local_history_view_test.go(假的 source):workbench/local_history_settings_test.go(真实 Core):desktop-go.sh vet ./internal/... ./cmd/...;i18n 三项;平台功能矩阵校验(255 项);全量desktop-go.sh test ./internal/... ./cmd/... -count=1(51 包)通过。第二十三轮(2026-11-12)Markdown 改为双栏编辑器(
15f23670a)chromeState.apply会跳过未知的位置 ID。led标记避免两边互相回弹。editor.markdownSourceView、editor.markdownSplitView、editor.markdownPreviewView加上 desktop 平台后复用;删除不再使用的desktop.markdown.noFile、desktop.markdown.title。editor.markdownViewModes是给整组按钮命名的词条,Viva 没有给控件组命名的接口,所以桌面端不用它。markdown-rendering、markdown-preview-outline的说明改为双栏编辑器;归档笔记里“工具窗口的 Markdown 预览”的说法同步改掉。workbench/markdown_preview_test.go重写,覆盖以下几项:desktop-go.sh vet ./internal/... ./cmd/...;i18n 三项;平台功能矩阵校验(255 项);Agent Notes 校验;全量desktop-go.sh test ./internal/... ./cmd/... -count=1通过。第二十四轮(2026-11-12)字体页改为“勾选位置 → 调整 → 保存”(
dedb1fde5)fontprefs.Assign(fonts, scopes, look)替换SetScope和Update。SameLook,自动行距视为相同);desktop.settings.fontsNoneChecked、desktop.settings.fontsEditHelp;改写desktop.settings.fontsOverviewHelp;删除fontsScope、fontsScopeHelp、fontsSeparate;复用ui.save与“还原”。editor-font-family的说明和验证步骤按新流程改写(“保存后生效,打开页面和编辑草稿都不写入”)。settingswindow/fonts_view_test.go:fontprefs:TestAssignSetsTheScopesGivenAndJoinsTheSameLook。desktop-go.sh test ./internal/... ./cmd/... -count=1(51 包)通过;i18n 三项(11660/11660)、功能矩阵 255 项、Agent Notes 232 篇通过。交接(2026-11-12,
dedb1fde5)分支已推送,工作区干净,没有遗留的 Lithe、cargo 或 go test 进程。固定版本未变:Core
d797244,Viva fork7850516be532。下一项是插件后端的 workspace 文件与搜索方法(API-06/07/08:
workspace/readDirectory、stat、readFile、watch、findFiles、findText)。代码还没写,已调研清楚的部分:shared/plugins/contract/v1/README.md的 “Public document, file and window methods” 一节;Core(plugin_function.rs)只检查权限,语义全部由宿主实现。旧 Swift 实现(PluginFileHostService.swift、MacPluginWorkspaceFileService.swift、MacPluginWorkspaceWatchHub.swift)可作行为参照。ListDirectories(排序、隐藏规则、省略符号链接都归 Core),搜索用SearchEverywherePage(resultKinds取file或content;Go 的EverywhereSearchRequest要补FileMask字段,Core 已支持),解码用DecodeFileBytes(identity也由它给出),纯文本判断用core.ClassifyDocumentText,监听结果过滤用FilterWorkspaceChanges。这几个方法不在pluginservice.Kernel里,用可选接口加类型断言,实现了才注册。openat+O_NOFOLLOW,放进documentio;Windows 逐段检查重解析点);读文件最多 128 KiB,读 max+1 字节判断是否截断,截断时尾部最多去掉 3 字节再解码;分页默认值与上限是目录 200/1000、搜索 100/200,搜索总数不超过 200;游标为不透明 base64 JSON,绑定 context、generation 和查询;每个调用方最多 4 个并发操作,超过返回limitExceeded。pluginservice不直接引用 Viva,经注入的 watcher 接口调用app.WatchDirectory/WatchTree,由工作台适配。每个调用方最多 32 个监听,总数最多 256;累计超过 1000 条路径或监听丢失事件时,只发requiresRescan。通知走lithe/host/subscriptions/notify,参数{subscriptionID, sequence, event:{rootID, changedPaths, requiresRescan}},sequence从 1 开始;订阅登记在s.resources.add,会话或 context 结束时释放。剩余工作
Page 迁移(已完成,每个窗口一个 Page;工作台根 Page 见
workbench/root.go):c862d812c补回)第一轮功能车道(已合入;逐项状态见功能矩阵):
Agent:工具时间线、思考、计划、上下文用量、模型调用与轮次统计、额度、子代理监控、斜杠命令、文件引用、中途补充输入、contextLimits;已归档对话;设置 › AI 的 Agents/指令/技能/Hooks 页;回复改用 Viva Markdown 视图;文件树右键“加入 Agent 会话”(第十轮删除)设置 › AI › MCP 配置页(发现 Codex/Claude 原生配置、保格式回写、备份回滚、所有权账本、注册表分页获取)(第十轮删除);Commit 面板生成提交信息;编辑器 AI 行内编辑(Cmd/Ctrl+K,差异审阅后接受);IDE broker 的 Core 封装debug/start、退出前确认运行中的程序、执行 PATH 走 Core第二轮功能车道(已合入):
.git元数据监听替换internal/gitmetadata、文件树右键菜单(Git 操作、新建/重命名/删除)683f2d51a)、本地变更列表(changelists*.go)、多仓库分组(409a1cc2f)、Rebase 计划编辑(第八轮历史改写)、worktree 检出已有分支(gitworktree.go)、Diff 内搜索与忽略空白(51858fd8d)、Diff 右侧可编辑(683f2d51a、48f1e39a4)、Diff 词内高亮(6256f1fa1)、Diff 分隔行分步展开(683f2d51a)、Shelf(第十三轮)step filters(56fea1512:设置卡片、启动携带、调用栈折叠)、(debug.target: launchd3474bba7)、startDebugging 子会话(需多会话调试窗口,宿主暂不声明该能力)、运行配置发现与编辑面板(50b5bce5a发现/选择/带保存选项运行,b2d103950编辑对话框:参数/工作目录/环境/保存范围,经 updateOptions 冲突检查后原子写回;providerRunOptions 编辑与 JDK/Maven 选择待做)、异常退出遗留进程清扫(第二十一轮;仅 macOS,Windows 没有进程台账)需要 Core 补(Lithe-core-rust#10 已合并,桌面已固定到 9e2e6f8):
applyToolchainSelection注入;execution.resolveEnvironment契约与 fixture 改为与工具无关的合并语义,Core 测试执行 fixture,桌面端去掉 skip 和无效字段debug.adapters.startArguments接受后端configuration并返回合并后的最终参数,桌面删掉 Go 端合并processLifecycle.resolve本就收idle,缺的是桌面探测——localshell.Shell.Busy(Unix TIOCGPGRP、Windows 子进程),退出/关闭项目/关闭标签页都会确认忙碌终端_meta.lithe.claudeDesktop:契约已有,补共享 fixtureshared/fixtures/agent/claude-desktop-cards-v1.json(六种卡片,Host 逐例重放);桌面端绘制卡片仍未做,见功能缺口text.decode/text.encode,桌面不再为编解码写临时目录Markdown 结构化输出:取消。换成 Core(Comrak)解析不能让图片显示,缺口在 Viva 的绘制能力(见 [API] Draw images in Markdown with host-supplied bitmaps vivaui/viva#220);数学、Mermaid 同理,等上游渲染能力与旧客户端的行为差异(已知,后续按需补):关闭确认问运行中的程序和忙碌终端(合并成一次确认,不逐个问、不能跳到终端;
exec替换后的 shell 和 Windows 上的 WSL 终端读作空闲);调试会话静默结束;Markdown 预览不渲染 HTML、数学、Mermaid;按编码重新打开时有未保存修改直接拒绝;引用改为面板;inline blame 只标光标行且不提供行号区菜单中的 annotate/close。功能缺口:
ui1 文本、ui2 包内网页)与 Web 页面桥接build.*桥接方法(本宿主不向页面提供构建系统);插件声明的窗口图标(暂用通用图标);ui.commands入口;ui3 原生树/列表;页面摄像头/麦克风授权;真机验收(web-panel 夹具显示、CSP 拦截、主题切换、状态往返)bb72e44e0;遗留终端与停止等待时间见第二十一轮)、快捷键(bd2350c89集中目录 + Keymap 页)、网络代理页与“测试连接”(第十九轮)、更新页(Vivaupdate)已完成;剩余:代理 Digest/NTLM 认证、自建更新通道的发布侧、AI 待定、构建工具栏选项(Maven profiles/settings/offline、Gradle offline/userHome)改为插件拥有的 settings2debug/start的 launch 目标、(第十六轮)、{kind:"tool"}启动走工具链解析editor/registerActions、registerProviders(第十六轮补 CodeLens 路由;foldingRange 未路由,Core 拒绝注册)、preview/openHTML(依赖 webview,暂缓)、workspace 文件与搜索方法(设计见上方“交接”)、卸载时清理凭据(Windows 凭据 2560 字节上限与契约 16 KiB 不一致)6a241bf0a)。四种类型、最多三条 toast、欢迎页入口已接通并在第二十二轮补测试;悬停或聚焦时暂停计时由 Vivaui.Toaster提供运行配置浏览列表(第十四轮;批量选择与并发运行、服务地址提示未做:前者需按配置的独立运行会话,后者需先把端口规则放进 Core)、插件 VCS provider 工具窗口(第十五轮;Annotate、单文件历史、gutter、元数据监听、fileOperations、项目树状态、ownerOf、VCS 控制台输出、冲突另一方、历史条目 Diff、authenticate 未做)、Shelf(第十三轮)、调试线程暂停/继续及监视行内编辑(第十一轮)、构建窗口测试入口(第十二轮)、依赖排除docs/viva-migration.md其余“必须迁移”项(AI、编辑器、扩展、运行调试、版本控制、工作区等);“放弃”19 项已确认,另有“放弃:Agent 对话”38 项(2026-11-12)e37e104bc,齿轮菜单“从旧版 Lithe 导入设置…”,macOS 读defaults export、Windows 读 Tauri store,逐项勾选、读回校验;日志目录有意不导入)、旧版插件清单(648327a52,列出未装插件并跳转市场重新安装,不复制旧包;旧启用状态不导入)app.lithe.viva(新产品,与旧 Lithe 并行安装,不做原地升级;旧 Lithe 停更到迁移完成)、签名、自建更新通道(不衔接旧 Sparkle 链)、新包自身的更新与回退演练91f2d83fc):原 116 项“尚未盘点”全部按 desktop/ 代码定状态与证据;macOS 现为 implemented 28、partial 124、missing 69、plugin-provided 24、platform-specific 10(共 255 项)。迁移文档“放弃/不纳入”的记 missing 并注明决定;部分实现的缺口写在各项 notes,作为后续补齐清单182f91a3e):Linux/Windows 上 Viva 自绘的窗口“Close”按钮被测试辅助函数误当成对话框按钮,TestClosingABusyTerminalTabAsksFirst自 05:11 起在 Linux 失败;查找时跳过标题栏按钮图层b680a1c(9d8f1edbe,第六轮改为 fork7edac95):页面浮层与声明式表单字段、ScrollArea 横向滚动、Flow、等宽单元格按字体度量、制表符号按单元格几何绘制、浮层按键与 ScrollAt 滚轮修复;macOS vet、viva vet、全量 50 包通过9d8f1edbe):vet 通过;测试 45 包通过、5 包 13 个失败,留到集中测试阶段修——8.3 短路径ADMINI~1与长路径不等同(localshell 终端目录、pluginservice 工作区、IDE API 配置)、mcpconfig 测试期望(第十轮随 Agent 对话删除)、/分隔idehelp 期望 Unix 权限位(第二十一轮)、workbench 附件拖放/插话文件为空(同上删除)、远程调试确认与运行输出链接 20s 超时、(第二十一轮,测试按平台分隔符构造路径;两项待实机复跑)documentsUnder返回 04a082940d):章节、建议回复、建议任务(在新对话中开始)、PR、目录;可视化只显示源码,渲染待 Viva fix(windows): 降低编辑器输入热路径开销,避免每键全文同步造成卡顿 #209–[Bug]windows平台下同时存在前端项目与JAVA项目时无法启动 #211合入后:
lithe-plugin-docs 运行:该仓库已退役(feat(plugins): 插件契约统一基线 0,契约与开发资料只在 Rust Core #1826),契约只在 Corecontract.mjs sync同步契约shared/plugins/,此项作废litheLogging时降级运行,解决 Cargo 0.1.3 在旧客户端起不来rust/contracts/ide-api/v1.md:旧 Windows 客户端随本 PR 删除后,改写其中仍说 Windows 提供 environment 与lithe_maven_*工具、尚未发送toolExposure的段落(d797244 的 Windows 段)Viva 上游(不阻塞功能开发,合并后升级):
Box.Shortcut生效,项目树的 F4 要靠它;升级固定版本时去掉TestProjectTreeOpenSelectedFollowsTheKeymap的 SkipINFO不再显示成INFCdesktop/go.mod与scripts/desktop/打包、图标脚本读取同一个 Viva 版本(脚本从go.mod解析出的源码目录构建工具,第六轮)编辑器性能基线(根窗口改为 Page,79997457f → a816b77,M4,
--count 6)110 项中 107 项在预算内。超预算 3 项是
SyntaxFullPassgo/java/markdown 100KiB,改动前已超(本次 +2%~+5%),不是本次引入。绘制、滚动、光标移动仍为 0 allocs;ViewPaint−10.6%~+3.9%,ViewType在 ±0.3% 内。ViewPrepareReload与Memory耗时 +5%~+23%,分配不变;本次只给 editorview/termview 各加了一个Bind,未触及这两条路径,按噪声记录,下次空闲机器复测。本轮改动编辑器绘制(gutter 标记、blame 注释)后再复测并更新数字。光标历史改动(
190c8252e)前后各跑一次editor-bench.sh run:112 项中 109 项在预算内,超预算的仍是同样 3 项既有SyntaxFullPass(go/java/markdown 100KiB),非本次引入;EditorViewUndoRedo100KiB 50.1→49.3 µs、10MiB 46.8→47.1 µs,EditorViewType在噪声范围内,无新增超预算。字体改动(editorview/termview 改为按字体绘制)前后各跑一次
editor-bench.sh run(M4):70 项全部在预算内,分配全部不变,绘制仍为 0 allocs;耗时变化 −1.5%~+5.8%,多数在 ±2% 内。最大的是PrepareReload/json/10MiB+5.8%、Open/java+4.7%/+3.5%,这两条路径未触及字体代码,且运行时机器上有其他编译任务,按噪声记录,下次空闲机器复测。Diff 标签页改为双编辑器(editorview 新增
diffdecor.go,paint.go接入行着色、行号标签与居中;gutter.go注释图标与横线;scrollbar.go可隐藏纵向条)前后各跑一次editor-bench.sh run --count 6(M4,基线为6f976b293工作区):112 项中 109 项在预算内,超预算的仍是既有 3 项SyntaxFullPass(go/java/markdown 100KiB,本次 +0.1%~+1.8%),非本次引入;分配全部不变,绘制、滚动、光标移动仍为 0 allocs。首轮ViewPaintcjk/mixed 显示 +6%~+16%,但单次样本 26~40 µs 波动明显;单独以--count 10复测ViewPaintplain/go/cjk/mixed,全部在 −0.2%~+4.3% 内,按噪声记录。PrepareReload/log/10MiB+9.1%、PrepareReload/json−11%~−20% 未触及本次代码,同为噪声。Diff 词内高亮(
6256f1fa1,editorview 新增行内范围底色)前后各跑一次editor-bench.sh run(M4,基线为6256f1fa1^的独立工作树,--count 6):改动前后均 70 项全部在预算内,分配全部不变,绘制、滚动、光标移动仍为 0 allocs;ViewPaint−0.5%~+8.3%,多数在 ±1% 内。变化较大的Memory/markdown/10MiB+31%、PrepareReload/log/10MiB+17% 未触及行内范围代码(没有设置行内范围时绘制只多一次空切片判断),且分配不变,按噪声记录。验证方式
每个改动跑相关包测试、gofmt、vet,以及仓库门禁(i18n 三项、功能矩阵、Agent Notes、运行时 bundle 只读、测试稳定性)。macOS/Windows 全量测试与原生 GUI 验收在阶段收尾时进行。改动编辑器模块时按
AGENTS.md“编辑器性能”一节做前后基线对比。i18n 测试需单独运行,与全量 Go 测试并行时曾出现 gofmt 子进程卡住(重跑即通过)。本轮实测(2026-11-10):
cd desktop && ../scripts/desktop/desktop-go.sh vet ./...通过;viva vet ./...0 条。desktop-go.sh test -count=1 -p 4 ./...:47 个包通过。generate-i18n.mjs --check、verify-app-language-localization.mjs、test-i18n.mjs(41 项)通过。verify-platform-feature-matrix.sh254 项通过。verify-agent-notes.sh232 篇通过;verify-runtime-bundle-immutability.sh通过。package-desktop.sh --no-sign --format app成功,bundle 内无lithe-mcp文件,嵌入字节与暂存辅助程序逐字节一致,生成文件已清理。Linux CI 修复(2026-11-11,
d8e0888c0、f2e21e1f5):go 1.26.0安装 Go,本机是 1.27.3,两版对长 map 键对齐不同。desktop/go.mod加toolchain go1.27.3,setup-go 读取该行。welcomeRevealLabel(),Search Everywhere 快捷键测试改用primaryModifier()(原测试写死 macOS 文案与 Cmd)。functionsChanged与ready都到;调试内存测试两次单步都等到paused已应用。desktop-go.sh test -count=1 -p 4 ./...通过;修复的两个竞态测试分别-count=40、-count=20全过;i18n、功能矩阵、测试稳定性门禁通过。TestStashTabMakesShowsPopsAndDropsStashes在859bd469c的 CI 上失败过一次,此后 9 次 CI 与本机-count=30均未复现,未做推测性修改。此前各节点的详细交接记录见本 PR 描述的编辑历史。