Skip to content

feat(windows): Git Log 多仓库体验与引用操作增强 - #883

Merged
1lck merged 3 commits into
1lck:previewfrom
kuun993:feat/git-log-repo-colors-actions
Sep 26, 2026
Merged

1lck merged 3 commits into
1lck:previewfrom
kuun993:feat/git-log-repo-colors-actions

Conversation

@kuun993

@kuun993 kuun993 commented Sep 25, 2026 •

Copy link
Copy Markdown
Contributor

背景

多仓库工作区(一个目录下有多个独立仓库,或主仓库 + 多个 git worktree)里 Git Log 的体验打磨:引用面板的分组/配色/交互,以及一批右键操作与项目树入口。

改动

引用面板

  • 多仓库时每个仓库一个稳定颜色,整组着色(浅色底 + 左侧色带 + 文件夹/仓库名同色);单仓库不着色。
  • 隐藏 refs/remotes/*/HEAD:它是远程默认分支的符号别名,不是可检出的独立分支。
  • 移除顶部 HEAD (Current Branch) 行(其右侧分支名冗余;要看当前分支日志点 Local 里的当前分支即可)。

交互 / 性能

  • 点击已选中的引用不再重复加载;跨仓库选中引用只加载一次(把待选引用交给历史控制器,避免"先切仓库加载默认分支、再加载目标分支"的两次加载与闪烁)。
  • 各仓库引用懒加载:只预载活动仓库,其它仓库展开时才读取并缓存;读取串行(避开 common-dir 写租约冲突);失败时显示错误并可重试。
  • 打开 Git Log 时触发工作区仓库发现;没有活动仓库时回退到第一个发现的仓库,不再误判"非 Git 仓库"。
  • 分支图颜色按分支名稳定(移植 IDEA 的 name-hash 思路),不再随拓扑变化跳色。

右键操作

  • 提交菜单:Revert Commit、Copy Short Hash。
  • 引用菜单:Copy Branch Name。
  • 项目树:git 仓库根目录右键新增 Git 子菜单(Open Git Log / Fetch / Pull… / Push… / New Branch…);下拉组件支持嵌套子菜单。

Pull

  • 新的 Pull 弹窗:可选择要拉取的远程分支(默认当前上游)+ 策略(默认 Merge、默认折叠);指定分支走 pullRemoteReference,上游沿用原 workflow,保留冲突 / 脏工作区 / 取消保护。

测试基建

说明:原本还有一处 blame 请求字段修复,但上游 #882 已用相同方式修好,已从本 PR 移除。

验证

  • cd windows/tauri && ./node_modules/.bin/tsc --noEmit ✅
  • bun test src/features/git → 338 pass / 0 fail(连跑 3 次确定性通过)✅
  • bun test src/features/file-explorer src/features/command-palette src/ui src/i18n → 47 pass ✅
  • scripts/verify-windows-boundaries.ps1 ✅
  • node scripts/verify-agent-notes.mjs ✅
  • verify-test-stability(--base origin/preview)✅

相关

@ghfind-review ghfind-review Bot added the review: medium ghfind author score; see https://ghfind.com label Sep 25, 2026
@kuun993
kuun993 force-pushed the feat/git-log-repo-colors-actions branch from ce4c671 to 94c4777 Compare September 25, 2026 08:09

@xiaoyumuxi xiaoyumuxi left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

审核结论

基于 94c47770e84aadfef3426584cd13b0e9028225ea,重点检查多仓库引用懒加载队列、对应 hook 测试、显式目标 Pull 的 workflow,以及项目树 Git 操作的目标传递。发现 1 处 P2 生命周期问题:只取消正在执行的引用读取,没有使已排队任务失效(见 inline)。

项目树新增的操作将点击时的仓库 path 显式传入 API/对话框,比执行时重新读取 active repository 更安全。Pull 显式 reference 不再被“当前上游已是最新”误挡,这部分分支处理方向正确。

建议

在队列修复之外,建议用 deferred promises 覆盖“旧工作区 A/B 排队 → 切到新工作区或关闭面板 → 旧请求完成”的行为,断言不会再启动旧仓库的读取,且新工作区不会被废弃队列拖延。串行化不能替代队列项本身的取消/失效检查。

验证边界

本轮是针对上述高风险路径的静态审查,不是对全部 59 个文件和交互的逐行/实机验收。查询本 head 返回的六个 Actions 工作流均为 completed/success;未在本地执行 Bun/Tauri 或 UI 测试。仅提交 Review 评论,不批准或合并。

requestedRepositoryKeysRef.current.add(repositoryKey);
pendingLoadCountRef.current += 1;
setState((current) => (current.isLoading ? current : { ...current, isLoading: true }));
const task = loadChainRef.current.then(() => loadRepository(repositoryPath));

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] 让排队中的读取也能在卸载/移除仓库时失效。这里把 loadRepository(repositoryPath) 延迟到前一个请求结束后才执行,而 operationId 和 generation 也是到执行时才创建。cleanup 只取消 activeOperationsRef 里的请求、清空 generation,无法取消这条尚未执行的 closure。可复现时序:A 的读取挂起,ensure B 入队,然后关闭面板;A 的取消完成后,B 仍会启动新的 native 读取,且已没有下一次 cleanup 负责取消它。移除 B 时也会先执行废弃读取,再在结果阶段发现不属于当前工作区。请在 enqueue 时捕获生命周期/仓库代数,并在真正调用 native API 前检查是否仍有效;失效队列项也需正确减少 pending 计数。增加 deferred-A + queued-B + unmount 的测试,断言 B 的 API 从未被调用。

@kuun993

kuun993 commented Sep 25, 2026

Copy link
Copy Markdown
Contributor Author

已按 inline 意见修复(a772486c)。

排队项不再等到真正执行时才创建生命周期 / 仓库代数:requestRepository 在入队时就占住该仓库的代数并记下面板生命周期代数,真正调用原生 API 前重新核对三件事 —— 面板没卸载、仓库仍在工作区、没有被更新的请求顶替。任一不成立就丢掉这条排队项,并调用 finishLoad() 把它占用的 pending 计数还回去,避免 isLoading 卡在 true。

回归测试 windows/tauri/src/features/git/hooks/use-git-workspace-references.test.tsx 新增两条:

  • deferred-A + 排队-B + 面板卸载:断言 B 的原生读取从未发生;
  • deferred-A + 排队-B + B 移出工作区:断言 B 的原生读取从未发生,且 pending 计数被回收、isLoading 回到 false。

两条测试在修复前均失败(未修复时 B 会真的发起读取)。

本机验证:tsc --noEmit 通过;bun test src/features/git 340 pass / 0 fail。

@lithe review

@kuun993
kuun993 force-pushed the feat/git-log-repo-colors-actions branch from a772486 to 8d2885e Compare September 25, 2026 22:47
@kuun993

kuun993 commented Sep 25, 2026

Copy link
Copy Markdown
Contributor Author

已 rebase 到最新 preview(b7add148,含 #891 的 Immer runtime 统一),当前 head 8d2885e8。

本分支未触碰 windows/tauri/vite.config.ts,rebase 后直接采用上游那份修复;本机重新验证:tsc --noEmit 通过,bun test src/features/git 340 pass / 0 fail,verify-windows-boundaries、verify-agent-notes、verify-test-stability 均通过。

@lithe review

@kuun993
kuun993 force-pushed the feat/git-log-repo-colors-actions branch from 8d2885e to 5df0186 Compare September 26, 2026 06:18
@kuun993

kuun993 commented Sep 26, 2026

Copy link
Copy Markdown
Contributor Author

已 rebase 到最新 preview(0a66c095),当前 head 5df01868。

这次上游也改了 shared/platform-feature-matrix.json 与 docs/development/platform-parity-matrix.{csv,md},rebase 自动合并后本机跑 generate-platform-feature-matrix.mjs --check 通过(两行的顺序与生成结果一致)。重新验证:tsc --noEmit 通过,bun test src/features/git 340 pass / 0 fail,verify-windows-boundaries、verify-agent-notes、verify-test-stability 均通过。

@lithe review

@1lck

1lck commented Sep 26, 2026

Copy link
Copy Markdown
Owner

@kuun993 这边也是一样 存在冲突 解决完冲突即可@我过来合入

@kuun993
kuun993 force-pushed the feat/git-log-repo-colors-actions branch from 5df0186 to 7746253 Compare September 26, 2026 07:17
@kuun993

kuun993 commented Sep 26, 2026

Copy link
Copy Markdown
Contributor Author

冲突已解决(head 77462534)。

冲突来自上游 #899 也改了 shared/platform-feature-matrix.json 与 docs/development/platform-parity-matrix.{csv,md}:JSON 与 CSV 自动合并成功,只有生成的 Markdown 冲突。处理方式是先把两边的功能条目合并进 JSON(79 条、无重复 id),再用 node scripts/generate-platform-feature-matrix.mjs 重新生成 CSV/MD,--check 通过 —— 生成物以 JSON 为唯一源头,不会手改后漂移。

重新验证:tsc --noEmit 通过,bun test src/features/git 340 pass / 0 fail,verify-windows-boundaries、verify-agent-notes、verify-test-stability 均通过。CI 已随推送重新触发。

@1lck 冲突已解决,可以合入了,谢谢!

@kuun993
kuun993 force-pushed the feat/git-log-repo-colors-actions branch from 7746253 to e8a4891 Compare September 26, 2026 10:18
@kuun993

kuun993 commented Sep 26, 2026

Copy link
Copy Markdown
Contributor Author

上游又前进了几步(#903 / #773·#910 / #890·#908),已跟着 rebase 到 f6b51485,当前 head e8a4891b。这次没有冲突(矩阵文件自动合并,JSON 79 条无重复,generate-platform-feature-matrix.mjs --check 通过)。

重新验证:tsc --noEmit 通过,bun test src/features/git 348 pass / 0 fail(上游 #910 在 git 区域新增了用例),verify-windows-boundaries、verify-agent-notes、verify-test-stability 均通过。

@1lck 已是最新 preview 上的可合并状态,麻烦你合一下,谢谢!

@kuun993
kuun993 force-pushed the feat/git-log-repo-colors-actions branch from e8a4891 to de1bc1e Compare September 26, 2026 11:17
@kuun993

kuun993 commented Sep 26, 2026

Copy link
Copy Markdown
Contributor Author

又跟了一次 preview(b1884c4f,含 #911 / #893),当前 head de1bc1e5。rebase 无冲突,矩阵 JSON 79 条无重复、生成物 --check 通过。

验证:tsc --noEmit 通过,bun test src/features/git 348 pass / 0 fail,verify-windows-boundaries、verify-agent-notes、verify-test-stability 均通过。CI 已随推送重新触发。

@1lck 目前是最新 preview 上的可合并状态,麻烦合一下,谢谢!

@kuun993
kuun993 force-pushed the feat/git-log-repo-colors-actions branch from de1bc1e to b375063 Compare September 26, 2026 13:17
@kuun993

kuun993 commented Sep 26, 2026

Copy link
Copy Markdown
Contributor Author

冲突已随上游 3fdb56ee(#878 PHP 插件)解决,当前 head b375063c。

冲突还是老位置:shared/platform-feature-matrix.json 与 CSV 自动合并成功,只有生成的 platform-parity-matrix.md 冲突。已把两边条目合并进 JSON(81 条、无重复 id,含上游 PHP 新增的 2 条),再用 generate-platform-feature-matrix.mjs 重新生成,--check 通过。

验证:tsc --noEmit 通过,bun test src/features/git 348 pass / 0 fail,verify-windows-boundaries、verify-agent-notes、verify-test-stability 均通过。CI 已重新触发。

@1lck 冲突已解决,麻烦合一下,谢谢!

多仓库工作区(如含多个独立仓库、或主仓库 + 多个 worktree)里的 Git 体验,围绕引用面板做了一组改进:

- 仓库配色:多仓库时每个仓库一个稳定颜色,整组着色(浅底 + 左侧色带 + 文件夹/仓库名同色);单仓库不着色。
- 引用面板:隐藏 `refs/remotes/*/HEAD`(远程默认分支的符号别名,不是独立分支);移除顶部 `HEAD (Current Branch)` 行。
- 交互:点击已选中的引用不再重复加载;跨仓库选中引用只加载一次(把待选引用传给历史控制器,避免先切仓库加载默认分支、再加载目标分支两次);各仓库引用改为懒加载(展开分组才读取),读取串行以避免 common-dir 写租约冲突;读取失败显示错误并可重试。
- 自动发现:打开 Git Log 时触发工作区仓库发现;没有活动仓库时回退到发现到的第一个仓库,不再误判为"非 Git 仓库"。
- 分支图颜色按分支名稳定(移植 IDEA 的 name-hash 思路),不再随拓扑变化跳色。
- 右键操作补齐:提交菜单新增 `Revert Commit`、`Copy Short Hash`;引用菜单新增 `Copy Branch Name`。
- 项目树:git 仓库根目录右键新增 `Git` 子菜单(Open Git Log / Fetch / Pull… / Push… / New Branch…);下拉组件支持嵌套子菜单。
- Pull 弹窗重做:可选择要拉取的远程分支(默认当前上游)+ 策略(默认 Merge、默认折叠);指定分支走 `pullRemoteReference`,上游沿用原 workflow 并保留冲突/脏工作区/取消保护。
- 修复 blame 请求字段:之前发送 `rootPath`,平台只把 `repoPath` 映射为 core 的 `root`,导致 `missing field 'root'`。
- 测试基建:修正 api 测试里对 platform 模块的部分 mock 造成的跨文件污染,`src/features/git` 全量测试恢复全绿。

验证:`tsc --noEmit`;`bun test src/features/git`(339);`file-explorer/command-palette/ui/i18n`(47);`verify-windows-boundaries.ps1`;`verify-agent-notes.mjs`;`verify-test-stability`。
`ensureRepository` 把 `loadRepository` 挂到串行链上,仓库代数和操作 id 却在真正执行时
才创建。于是清理只能取消 `activeOperationsRef` 里正在执行的操作,取消不了还没执行的
closure:A 的读取挂起、B 入队、面板关闭后,A 的取消完成,B 仍会启动一次没有任何人负责
取消的原生读取;仓库从工作区移除时也会先执行一次废弃读取,只在结果阶段才发现它已不属于
当前工作区。

现在在入队时就占住仓库代数并记下面板生命周期代数,真正调用原生 API 前重新核对三件事:
面板没卸载、仓库仍在工作区、没有被更新的请求顶替。任一不成立就丢掉这条排队项,并调用
`finishLoad()` 归还它占用的 pending 计数,避免 `isLoading` 卡在 true。

新增两条回归测试:deferred-A + 排队-B + 面板卸载、deferred-A + 排队-B + B 移出工作区,
都断言 B 的原生读取从未发生;后者同时断言 pending 计数回收、`isLoading` 回到 false。
两条测试在修复前均失败。
@kuun993
kuun993 force-pushed the feat/git-log-repo-colors-actions branch from b375063 to f238f34 Compare September 26, 2026 14:20
@kuun993

kuun993 commented Sep 26, 2026

Copy link
Copy Markdown
Contributor Author

已跟到最新 preview(04122aac,#907),当前 head f238f341。

rebase 后生成的 platform-parity-matrix.md 头部统计没跟上 JSON(功能项 81 → 82,因为 #878 / #907 各加了一行),已用 node scripts/generate-platform-feature-matrix.mjs 重新生成并折叠进本 PR 的功能提交里,--check 通过(JSON 82 条、无重复 id)。

验证:tsc --noEmit 通过,bun test src/features/git 348 pass / 0 fail,verify-windows-boundaries、verify-agent-notes、verify-test-stability 均通过。CI 已重新触发。

@1lck 目前是最新 preview 上的可合并状态,麻烦合一下,谢谢!

@1lck
1lck merged commit ca3d070 into 1lck:preview Sep 26, 2026
3 of 4 checks passed
1lck added a commit that referenced this pull request Sep 26, 2026
… (#900)

* feat(windows): align default shell setting with detected shells (#895)

- Build the Settings > Terminal default shell options from the same shell
  discovery list used by the terminal "New Terminal" menu, so Git Bash,
  PowerShell 7 and each WSL distribution can be chosen.
- Load shells when the panel opens and add a "Detect Installed Shells"
  button with loading and failure states, matching the macOS settings page.
- Keep a saved shell that is no longer detected visible as "Not detected"
  instead of showing a different shell (e.g. the legacy bare "wsl" id).
- Remove the unused hardcoded shell locale keys.
- Update the terminal-shell row of the platform feature matrix.

* feat(windows): move new terminal actions next to terminal tabs (#895)

- In the horizontal terminal tab bar, render the "New Terminal" (+) and
  "Choose terminal profile" buttons right after the last tab instead of at
  the far right, so they stay close when working with several terminals.
- Let the tab list size to its tabs and scroll once they overflow, keeping
  the new terminal buttons visible at the end of the tab area.
- Keep search and full screen as trailing panel actions; the vertical tab
  sidebar layout is unchanged.
- Left-align the profile menu with its trigger; the dropdown already clamps
  itself inside the viewport.
- Update the terminal-sessions row of the platform feature matrix.

* feat(windows): always show close buttons on terminal tabs (#895)

- Show the close (x) button on every terminal tab instead of only the
  active tab, so inactive terminals can be closed without hovering or
  switching to them first. This matches the macOS terminal tabs.
- Pinned tabs keep showing the unpin button as before.

* feat(windows): add minimize button to the terminal panel (#895)

- Add a "Minimize Terminal" (-) button at the end of the terminal tab bar
  toolbar, including the empty-state bar, mirroring the macOS "Hide
  Terminal tool window" button.
- Minimizing hides the bottom pane while terminal sessions keep running;
  it also leaves full screen so reopening restores the docked panel.
- Add the terminal.minimizeTerminal locale strings (en / zh).
- Update the terminal-sessions row of the platform feature matrix.

* fix(windows): stop git graph lanes from extending above branch tips

- A commit that starts a lane (a branch tip such as HEAD) has no child row
  above it, but its lane was still reported as incoming, so the graph drew
  a line segment above the commit dot. Mark that lane as having no
  incoming segment so the line starts at the dot.
- Give each graph row its own node color so the dot keeps its lane color
  instead of relying on the incoming segment.
- Add a layout regression test and update the git-history row of the
  platform feature matrix.

* fix(windows): keep new terminal actions visible with many pinned tabs (#895)

Addresses review feedback on #900.

- Put pinned and regular terminal tabs in one shared horizontal scroll
  area. Previously the non-shrinking pinned group sat beside the regular
  tab scroller inside an overflow-hidden wrapper, so enough pinned tabs
  clipped the "+ / ▾" buttons.
- Render the "+ / ▾" actions as a non-shrinking sibling outside the scroll
  area via a new HorizontalTerminalTabStrip component.
- Extract shared tab rendering and wheel scrolling helpers; the vertical
  tab sidebar layout is unchanged.
- Add a structural regression test for many pinned tabs, many regular
  tabs, and mixed pinned + regular tabs.

* fix(macOS): 统一活动栏与 Maven 悬停提示并适配文字宽度 (#899)

* fix(macos): add compact Maven toolbar tooltips

Refs #898

* fix(macos): Match settings titlebar to panel background (#896)

* fix(macos): match settings titlebar to panel background

* docs: record settings titlebar in platform matrix

* test(macos): cover settings window chrome appearance

---------

Co-authored-by: Xiaoyumuxi <3075514079@qq.com>

* fix(macos): stabilize activity rail hover tooltips

Share a window-local hover owner, retain compact measured tooltip layout, and add regression coverage for switching and rendering. Refs #898.

---------

Co-authored-by: arkleselect <166632698+arkleselect@users.noreply.github.com>
Co-authored-by: Xiaoyumuxi <3075514079@qq.com>

* fix(maven): 依赖树改为读取插件输出文件,日志与数据分离(macOS + Windows,#890) (#908)

* fix(maven): read dependency trees from the plugin's output file (#890)

The Maven tool window parsed the dependency tree out of the whole console
output, so the tree shared one 500,000-character budget with Maven's log.
Large projects (6,000 nodes is about 700 KB) failed with "Maven dependency
output exceeded the supported limit." on both macOS and Windows.

The dependency plugin now writes the verbose text tree to a platform-owned
scratch file through -DoutputFile, and Core reads that file. Console output
is log only.

Core
- maven.dependencyPlan takes a required absolute outputFile and pins every
  format-affecting property (text, standard tokens, UTF-8, overwrite). The
  reactor root runs with -N so only one project writes the file.
- maven.dependencies takes { modulePath, outputFile } and validates the file
  strictly: the root line, then only well-formed nodes with annotations the
  pinned plugin writes. Unknown content fails with parse_failed instead of
  producing a partial tree; a missing file is process_failed.
- Bounds come from the tree (10,000 nodes, 64 levels, 4 KiB lines, a byte
  limit derived from those), not from log volume.
- Nodes now carry premanagedVersion, premanagedScope, originalScope, and
  ignoredScope from the verbose annotations that were previously dropped.
- The shared fixture moves to dependency-tree-v2.json.

Windows
- The Tauri host creates and removes one scratch file per dependency session
  in the app cache directory and clears the directory at startup.
- The Maven store no longer buffers dependency output; every path that ends
  a session (read, cancel, timeout, failure, invalidation, supersession)
  removes the file, and only after Core has read it.

macOS
- New MavenDependencyOutputStoring port, implemented by
  MacMavenDependencyOutputStore with a per-process directory; directories of
  exited processes are removed so concurrent Lithe builds keep their files.
- MavenService follows the same lifecycle as Windows.

Both dependency trees show the new management and scope annotations. The
decision and rejected alternatives (JDT LS/m2e, JSON output, a Maven Server,
raising the limit) are recorded in an Agent Note.

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

* style(windows): realign Maven dependency state updates

Removing the dependency output buffer left four closing braces of set()
calls indented one level too deep in maven.store.ts.

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

* test(macos): run the Maven tree bridge test only where Core is linked

The ordinary Swift unit lane does not link Rust Core, so the end-to-end
dependency-tree test failed there with "Rust Core is unavailable". Move it
into MavenDependencyTreeBridgeTests, gate it on RustCoreBridge.isAvailable as
the other bridge tests do, and add the suite to the Core-linked lane in
verify-rust-core.sh so CI still runs it.

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

---------

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

* fix(windows): keep working-tree diffs open and scrollable (#773) (#910)

- Ignore Core temporary Git contexts (.git/lithe-commit-*) in the Git
  metadata watcher so opening a snapshot diff no longer triggers a refresh.
- Refresh a working-tree file diff with the same repository, path, and
  HEAD-to-worktree snapshot used to open it; show an empty state when no diff
  remains and close only when Git status no longer lists the file (macOS
  behavior). Failed or stale refreshes keep the current content, and
  identical results leave the buffer untouched.
- Save the Monaco view state before removing hunk action zones so updates no
  longer drift a scrolled diff upward.
- Let a single working-tree text diff fill the diff area with Monaco as the
  only scroller, fixing wheel scrolling that could not reach the bottom.

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

* fix(macos): clarify workbench dividers over background images (#903)

* fix(macos): show workbench pane dividers over background images

* fix(macos): render visible gutters over workbench backgrounds

* style(macos): soften background split gutters

---------

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

* fix(macos): 将运行时生成内容排除在更新检查的认证逻辑上,避免频繁的降级到全量更新 (#893)

* fix(macos): keep runtime bundle immutable for delta updates

* docs: record runtime bundle update invariant

* fix(macos): reject bundle-local JDTLS caches

* fix(macos): classify symlinked JDTLS bundles safely

* test(macos): use unique JDTLS symlink fixture

* fix(macos): reject incomplete and linked JDTLS caches

* fix(lsp): keep packaged JDTLS read-only on macOS and Windows

Equinox writes its framework state into the directory passed as
-configuration. Both products passed the packaged config_mac*/config_win
directory, so the first Java launch modified the installed app bundle
(breaking Sparkle deltas) and the Windows installation directory.

Rust Core now copies the packaged config.ini, the only file JDT LS ships
there, into cacheDirectory/jdtls-configuration/<sha256>/configuration and
passes that area instead, for both hosts:
- the SHA-256 of config.ini (which lists every bundle version) selects a
  fresh area after a JDT LS upgrade;
- a missing or damaged copy is rewritten atomically, so a broken cache can
  no longer disable Java with a misleading "Reinstall Lithe" error;
- a cache that resolves inside the JDT LS installation, including through
  a symlink, is rejected before anything is written;
- areas unused for the shared 30-day JDT retention period are removed.

This replaces the macOS-only Swift resolver copy, which is reverted. The
real JDT LS smoke test now asserts the installation's file listing is
unchanged after import, build, and classpath resolution; with the old
behavior it fails on org.eclipse.osgi appearing in the packaged config.

The rules move from AGENTS.md into the develop-lithe Skill, the guard
script keeps only the generic Swift bundle-write scan, and the Agent
Note, Core contract, update docs, and feature matrix describe the Core
behavior.

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

---------

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

* fix (windows): 修复诊断日志导出弹窗溢出(UI 变化) (#911)

* fix(windows): contain diagnostic export preview

* docs: track diagnostic export dialog layout

---------

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

* PHP 支持改为按需安装的官方插件 (#878)

* PHP 语言支持升级为官方原生插件

* docs(release): prepare Lithe v0.5.3

Covers preview commits 5c29782..56f6fdb (#733, #823, #837, #838, #839,
#841, #843); #756 is developer tooling and #846 carries no code change.
The range starts at 5c29782 rather than v0.5.2 because #821 was squashed
into main, so v0.5.2's commits would otherwise be counted again.

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

* lithe 0.5.3

* 修复windows php lsp windows支持问题

* docs(release): prepare Lithe v0.5.4

* fix(ci): align macOS package fixture with Java Test manifest

* lithe 0.5.4

* refactor: make optional plugins truly on demand and move built-in resources out of marketplace (#879)

* refactor(plugins): enforce on-demand lifecycle and internal resource ownership

* fix(plugins): restore macOS build and keep built-in themes out of marketplace

* fix(plugins): keep disabled extensions inactive through updates

* ci: remove retired LinuxDo WebKit test lanes

* feat(editor): 支持多种编码格式的打开与保存 (#875)

* feat(editor): support document encoding switching

Add VS Code-style reopen and save with encoding workflows for macOS and Windows, including GBK/GB18030 support, guarded persistence, session restoration, and cross-platform feature documentation.

* fix(editor): separate document read and save encodings

* fix(editor): ignore self-save encoding notifications

* fix(editor): show explicit encoding decode results

* fix(windows): preserve save identity across retries

* fix(macos): reduce WorkbenchView type-check complexity

* fix(windows): distinguish undecodable conflicts from missing files

---------

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

* chore: 跨平台功能对齐表格生成与维护 (#851)

* chore: track cross-platform feature parity

* refine: split feature parity into capabilities

* docs: expand initial platform capability inventory

* fix: address platform matrix review feedback

* fix: address remaining platform matrix review findings

* perf(windows): 关闭终端诊断时的额外采样 (#871)

Cover diagnostic resource creation, toggle cleanup, and terminal unmount in the Windows frontend tests.

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

* fix(windows): prevent Git discovery startup contention (#788) (#882)

* fix(windows): prevent Git discovery startup contention (#788)

* test(windows): type Git blame invoke mock

* test(rust): normalize repository root assertion

---------

Co-authored-by: milestone <345198561@qq.com>
Co-authored-by: Lichenkang <2188718831@qq.com>

* fix(windows): unify Immer runtime for Zustand middleware (#891)

* fix(macos): Match settings titlebar to panel background (#896)

* fix(macos): match settings titlebar to panel background

* docs: record settings titlebar in platform matrix

* test(macos): cover settings window chrome appearance

---------

Co-authored-by: Xiaoyumuxi <3075514079@qq.com>

* fix(macOS): 统一活动栏与 Maven 悬停提示并适配文字宽度 (#899)

* fix(macos): add compact Maven toolbar tooltips

Refs #898

* fix(macos): Match settings titlebar to panel background (#896)

* fix(macos): match settings titlebar to panel background

* docs: record settings titlebar in platform matrix

* test(macos): cover settings window chrome appearance

---------

Co-authored-by: Xiaoyumuxi <3075514079@qq.com>

* fix(macos): stabilize activity rail hover tooltips

Share a window-local hover owner, retain compact measured tooltip layout, and add regression coverage for switching and rendering. Refs #898.

---------

Co-authored-by: arkleselect <166632698+arkleselect@users.noreply.github.com>
Co-authored-by: Xiaoyumuxi <3075514079@qq.com>

* fix(maven): 依赖树改为读取插件输出文件,日志与数据分离(macOS + Windows,#890) (#908)

* fix(maven): read dependency trees from the plugin's output file (#890)

The Maven tool window parsed the dependency tree out of the whole console
output, so the tree shared one 500,000-character budget with Maven's log.
Large projects (6,000 nodes is about 700 KB) failed with "Maven dependency
output exceeded the supported limit." on both macOS and Windows.

The dependency plugin now writes the verbose text tree to a platform-owned
scratch file through -DoutputFile, and Core reads that file. Console output
is log only.

Core
- maven.dependencyPlan takes a required absolute outputFile and pins every
  format-affecting property (text, standard tokens, UTF-8, overwrite). The
  reactor root runs with -N so only one project writes the file.
- maven.dependencies takes { modulePath, outputFile } and validates the file
  strictly: the root line, then only well-formed nodes with annotations the
  pinned plugin writes. Unknown content fails with parse_failed instead of
  producing a partial tree; a missing file is process_failed.
- Bounds come from the tree (10,000 nodes, 64 levels, 4 KiB lines, a byte
  limit derived from those), not from log volume.
- Nodes now carry premanagedVersion, premanagedScope, originalScope, and
  ignoredScope from the verbose annotations that were previously dropped.
- The shared fixture moves to dependency-tree-v2.json.

Windows
- The Tauri host creates and removes one scratch file per dependency session
  in the app cache directory and clears the directory at startup.
- The Maven store no longer buffers dependency output; every path that ends
  a session (read, cancel, timeout, failure, invalidation, supersession)
  removes the file, and only after Core has read it.

macOS
- New MavenDependencyOutputStoring port, implemented by
  MacMavenDependencyOutputStore with a per-process directory; directories of
  exited processes are removed so concurrent Lithe builds keep their files.
- MavenService follows the same lifecycle as Windows.

Both dependency trees show the new management and scope annotations. The
decision and rejected alternatives (JDT LS/m2e, JSON output, a Maven Server,
raising the limit) are recorded in an Agent Note.

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

* style(windows): realign Maven dependency state updates

Removing the dependency output buffer left four closing braces of set()
calls indented one level too deep in maven.store.ts.

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

* test(macos): run the Maven tree bridge test only where Core is linked

The ordinary Swift unit lane does not link Rust Core, so the end-to-end
dependency-tree test failed there with "Rust Core is unavailable". Move it
into MavenDependencyTreeBridgeTests, gate it on RustCoreBridge.isAvailable as
the other bridge tests do, and add the suite to the Core-linked lane in
verify-rust-core.sh so CI still runs it.

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

---------

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

* fix(windows): keep working-tree diffs open and scrollable (#773) (#910)

- Ignore Core temporary Git contexts (.git/lithe-commit-*) in the Git
  metadata watcher so opening a snapshot diff no longer triggers a refresh.
- Refresh a working-tree file diff with the same repository, path, and
  HEAD-to-worktree snapshot used to open it; show an empty state when no diff
  remains and close only when Git status no longer lists the file (macOS
  behavior). Failed or stale refreshes keep the current content, and
  identical results leave the buffer untouched.
- Save the Monaco view state before removing hunk action zones so updates no
  longer drift a scrolled diff upward.
- Let a single working-tree text diff fill the diff area with Monaco as the
  only scroller, fixing wheel scrolling that could not reach the bottom.

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

* fix(macos): clarify workbench dividers over background images (#903)

* fix(macos): show workbench pane dividers over background images

* fix(macos): render visible gutters over workbench backgrounds

* style(macos): soften background split gutters

---------

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

* fix(macos): 将运行时生成内容排除在更新检查的认证逻辑上,避免频繁的降级到全量更新 (#893)

* fix(macos): keep runtime bundle immutable for delta updates

* docs: record runtime bundle update invariant

* fix(macos): reject bundle-local JDTLS caches

* fix(macos): classify symlinked JDTLS bundles safely

* test(macos): use unique JDTLS symlink fixture

* fix(macos): reject incomplete and linked JDTLS caches

* fix(lsp): keep packaged JDTLS read-only on macOS and Windows

Equinox writes its framework state into the directory passed as
-configuration. Both products passed the packaged config_mac*/config_win
directory, so the first Java launch modified the installed app bundle
(breaking Sparkle deltas) and the Windows installation directory.

Rust Core now copies the packaged config.ini, the only file JDT LS ships
there, into cacheDirectory/jdtls-configuration/<sha256>/configuration and
passes that area instead, for both hosts:
- the SHA-256 of config.ini (which lists every bundle version) selects a
  fresh area after a JDT LS upgrade;
- a missing or damaged copy is rewritten atomically, so a broken cache can
  no longer disable Java with a misleading "Reinstall Lithe" error;
- a cache that resolves inside the JDT LS installation, including through
  a symlink, is rejected before anything is written;
- areas unused for the shared 30-day JDT retention period are removed.

This replaces the macOS-only Swift resolver copy, which is reverted. The
real JDT LS smoke test now asserts the installation's file listing is
unchanged after import, build, and classpath resolution; with the old
behavior it fails on org.eclipse.osgi appearing in the packaged config.

The rules move from AGENTS.md into the develop-lithe Skill, the guard
script keeps only the generic Swift bundle-write scan, and the Agent
Note, Core contract, update docs, and feature matrix describe the Core
behavior.

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

---------

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

* fix (windows): 修复诊断日志导出弹窗溢出(UI 变化) (#911)

* fix(windows): contain diagnostic export preview

* docs: track diagnostic export dialog layout

---------

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

* fix: distribute Windows PHP support as an independent worker plugin

* test: bound plugin worker integration with framework timeout

---------

Co-authored-by: Lichenkang <2188718831@qq.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: muchen <145200703+Mucheen@users.noreply.github.com>
Co-authored-by: dudylan <34180156+dudylan@users.noreply.github.com>
Co-authored-by: waani <kuun993@163.com>
Co-authored-by: xtr-hub <xtr-hub@qq.com>
Co-authored-by: Weii <fengwei5207@163.com>
Co-authored-by: Xiaoyumuxi <3075514079@qq.com>
Co-authored-by: LuoBiao <3451978561@qq.com>
Co-authored-by: milestone <345198561@qq.com>
Co-authored-by: arkleselect <166632698+arkleselect@users.noreply.github.com>
Co-authored-by: 若水 <frankw.wang@qq.com>

* fix(windows): align activity rails and fix minimap gutter bleed (UI) (#907)

* fix(windows): align activity rail edges

* docs: track activity rail edge alignment

* fix(windows): cover minimap and scrollbar gutters

* chore: regenerate platform feature matrix views

---------

Co-authored-by: Xiaoyumuxi <3075514079@qq.com>
Co-authored-by: Yao Jingxi <23722032@bjtu.edu.cn>

* fix(run): keep module services listed when their working directory is overridden (#861) (#912)

Resolution checked `extensions.maven.module` against the effective `cwd`, so
setting a multi-module service's working directory to its own module looked for
`web/web`, reported `missingModule`, and dropped the configuration from the
run list. The module is now checked against the Core-derived reactor
(`extensions.maven.reactorPath`, or the root without detected ownership).

`runConfig.updateOptions` also accepted directories that do not exist, including
editor variables such as `${workspaceFolder}/web`, which resolution then
disabled and hid. Working-directory overrides must now name an existing
directory inside the project, and variables are rejected with a specific
message the editor shows on save.

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

* feat(macos): Git Log 多仓库引用分组、仓库配色与右键操作补齐 (#884)

* feat(macos): Git Log 多仓库引用分组、仓库配色与右键操作补齐

- 引用面板按仓库分组:多仓库时顶层每个仓库一个可折叠节点(名称 + 数量),组内仍是 Local / Remote / Tags;单仓库渲染不变。
- 仓库配色:每个仓库一个稳定颜色,整组着色(浅底 + 左侧色带 + 图标/名称同色);单仓库不着色。
- 非活动仓库分组只读:写操作菜单(检出/删除/推送/重命名/合并/newBranch 等)只出现在活动仓库分组;点击行仍是选择(先切换活动仓库)。
- 右键操作补齐:`Set/Clear Upstream`(Tracking Branch 子菜单,列出远程分支)、`Copy Branch Name`、`Reset` 支持 soft/mixed/hard(hard 需确认,提示会丢弃工作区改动)。
- 各仓库引用加载移出 `refreshGitHistory` 的发布关键路径(与图构建并行、发布后 await),避免发布旧 generation 页面、也不再阻塞提交列表。
- 复用 Core 已支持的 `setUpstream`/`unsetUpstream`,新增 GitService/RustGitOperations 管道与 GitFeatureModel 方法;无 Rust/Core 契约改动。
- 本地化(en + zh-Hans)与相关 Swift 测试同步更新;更新 Agent Note。

验证:本机无 Swift 工具链,未本地编译;`verify-agent-notes.mjs` 与 `verify-test-stability` 通过,其余交由 macOS CI(swift 测试 + 边界校验)。

* fix(macos): 引用行相等判断纳入远程分支列表

`GitReferenceRowView` 以 `.equatable()` 渲染,只有 `==` 判不相等的行才会重建,但
`==` 不比较 Tracking Branch 子菜单读取的远程分支列表——它放在被比较逻辑刻意忽略的
`GitReferenceRowActions` 里。于是一次只增删远程分支的 `refs` 刷新(本地分支、选中和
执行状态都没变)不会让行失效,子菜单继续用建行时捕获的旧列表:已删的远程分支还在列,
或明明出现了远程分支仍显示 “No Remote Branches”。

把这份快照从 `actions` 移出、作为 `GitReferenceRowView` 自己的值属性,并把整条相等
契约抽成 `GitReferenceRowRenderKey`(定义在 `GitReferenceRows.swift`),`==` 只比较
这个 key,新增被行或菜单读取的字段必须进 key 才会生效。非活动仓库分组只读、菜单不
出现,传空列表避免无谓重建。

新增 `GitReferenceRowRenderKeyTests.swift`:只增远程分支、只删远程分支都必须判不相等,
列表不变判相等,行自身字段变化仍然判不相等。

* chore(matrix): regenerate platform parity views

---------

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

* feat(windows): Git Log 多仓库体验与引用操作增强 (#883)

* feat(windows): Git Log 多仓库体验与引用操作增强

多仓库工作区(如含多个独立仓库、或主仓库 + 多个 worktree)里的 Git 体验,围绕引用面板做了一组改进:

- 仓库配色:多仓库时每个仓库一个稳定颜色,整组着色(浅底 + 左侧色带 + 文件夹/仓库名同色);单仓库不着色。
- 引用面板:隐藏 `refs/remotes/*/HEAD`(远程默认分支的符号别名,不是独立分支);移除顶部 `HEAD (Current Branch)` 行。
- 交互:点击已选中的引用不再重复加载;跨仓库选中引用只加载一次(把待选引用传给历史控制器,避免先切仓库加载默认分支、再加载目标分支两次);各仓库引用改为懒加载(展开分组才读取),读取串行以避免 common-dir 写租约冲突;读取失败显示错误并可重试。
- 自动发现:打开 Git Log 时触发工作区仓库发现;没有活动仓库时回退到发现到的第一个仓库,不再误判为"非 Git 仓库"。
- 分支图颜色按分支名稳定(移植 IDEA 的 name-hash 思路),不再随拓扑变化跳色。
- 右键操作补齐:提交菜单新增 `Revert Commit`、`Copy Short Hash`;引用菜单新增 `Copy Branch Name`。
- 项目树:git 仓库根目录右键新增 `Git` 子菜单(Open Git Log / Fetch / Pull… / Push… / New Branch…);下拉组件支持嵌套子菜单。
- Pull 弹窗重做:可选择要拉取的远程分支(默认当前上游)+ 策略(默认 Merge、默认折叠);指定分支走 `pullRemoteReference`,上游沿用原 workflow 并保留冲突/脏工作区/取消保护。
- 修复 blame 请求字段:之前发送 `rootPath`,平台只把 `repoPath` 映射为 core 的 `root`,导致 `missing field 'root'`。
- 测试基建:修正 api 测试里对 platform 模块的部分 mock 造成的跨文件污染,`src/features/git` 全量测试恢复全绿。

验证:`tsc --noEmit`;`bun test src/features/git`(339);`file-explorer/command-palette/ui/i18n`(47);`verify-windows-boundaries.ps1`;`verify-agent-notes.mjs`;`verify-test-stability`。

* fix(windows): 排队中的引用读取在卸载或移出工作区后不得发起原生读取

`ensureRepository` 把 `loadRepository` 挂到串行链上,仓库代数和操作 id 却在真正执行时
才创建。于是清理只能取消 `activeOperationsRef` 里正在执行的操作,取消不了还没执行的
closure:A 的读取挂起、B 入队、面板关闭后,A 的取消完成,B 仍会启动一次没有任何人负责
取消的原生读取;仓库从工作区移除时也会先执行一次废弃读取,只在结果阶段才发现它已不属于
当前工作区。

现在在入队时就占住仓库代数并记下面板生命周期代数,真正调用原生 API 前重新核对三件事:
面板没卸载、仓库仍在工作区、没有被更新的请求顶替。任一不成立就丢掉这条排队项,并调用
`finishLoad()` 归还它占用的 pending 计数,避免 `isLoading` 卡在 true。

新增两条回归测试:deferred-A + 排队-B + 面板卸载、deferred-A + 排队-B + B 移出工作区,
都断言 B 的原生读取从未发生;后者同时断言 pending 计数回收、`isLoading` 回到 false。
两条测试在修复前均失败。

---------

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

* feat(update): offer the install action where an update check finds one (#853) (#914)

A manual update check that found a new version only changed the status: the
person then had to find the title bar indicator, open its details and click
Install.

macOS and Windows now open the update details, with release notes and the
install action, when a check from the menu or the Welcome/title bar control
finds an update. Scheduled checks still only show the title bar indicator.
Settings keeps the result inline and shows a primary install button next to
the check button.

- macOS: a single Software Update window replaces the title bar sheet and is
  opened through UpdateChecker.presentDetails(), installed from the scene
  bridge like the other window callbacks.
- Windows: the update store owns whether the details dialog is open and one
  AppUpdateDetailsDialog is mounted per window; the Settings update panel
  gains the install button it was missing.

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

* 修复超长命令与运行时资源写入导致的更新问题 (#888)

* fix: shorten oversized Java and terminal commands

Resolve issue #868 by keeping large Java launch arguments in argfiles and routing oversized Windows cmd.exe and PowerShell terminal input through temporary scripts. Preserve shell behavior for ordinary interactive input, clean temporary files with connection lifecycle, and document platform verification boundaries.

* fix(ci): avoid unavailable rg in macOS guard

* fix(windows): handle shell script execution limits

* fix(windows): report and bound CMD terminal input

* fix(windows): release terminal writer before errors

* fix(windows): preserve terminal input submission boundaries

---------

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

* 草稿:对齐 IDEA Community 工作台外框、主题色与活动栏图标 (#909)

* style(macos): 对齐 IDEA Community 工作台外观与工具栏图标

* fix(macos): 防止窄侧栏遮挡活动栏和分隔区

* fix(macos): 保持窄侧栏右侧圆角可见

* fix(macos): 修复窄侧栏布局与活动栏可见性

---------

Co-authored-by: Lichenkang <2188718831@qq.com>
Co-authored-by: muchen <145200703+Mucheen@users.noreply.github.com>
Co-authored-by: arkleselect <166632698+arkleselect@users.noreply.github.com>
Co-authored-by: Xiaoyumuxi <3075514079@qq.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: xtr-hub <xtr-hub@qq.com>
Co-authored-by: jay <917647288@qq.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: dudylan <34180156+dudylan@users.noreply.github.com>
Co-authored-by: waani <kuun993@163.com>
Co-authored-by: Weii <fengwei5207@163.com>
Co-authored-by: LuoBiao <3451978561@qq.com>
Co-authored-by: milestone <345198561@qq.com>
Co-authored-by: Yao Jingxi <23722032@bjtu.edu.cn>
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