Skip to content

fix(workspace): 会话变更文件列表优化 —— 树状/列表切换、视觉统一、异步构建等待#5245

Open
ttmouse wants to merge 4 commits into
esengine:main-v2from
ttmouse:fix/workspace-changes-display
Open

fix(workspace): 会话变更文件列表优化 —— 树状/列表切换、视觉统一、异步构建等待#5245
ttmouse wants to merge 4 commits into
esengine:main-v2from
ttmouse:fix/workspace-changes-display

Conversation

@ttmouse

@ttmouse ttmouse commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

问题

Issue #4544: Agent 修改代码后,右下角的「本会话变更」为空,仅展示了 git 提交记录。

根因

  1. checkpoint.List() 屏蔽当前 turn 的文件路径 — AI 刚改完文件后,Store.List() 把当前 turn 的 Paths 设为 nil,必须等用户发下条消息后才可见
  2. 异步 Controller 构建竞态 — startTabControllerBuild 在 goroutine 中执行,切换对话时前端立即请求数据但 tab.Ctrl 仍为 nil,checkpoint 数据被跳过
  3. 切换对话不刷新面板 — handleOpenTopic 和 onResumeSession 未 bump dockRefreshKey

测试

  • go test ./internal/checkpoint/... — checkpoint 全部 PASS
  • go test ./desktop/ -run TestCheckpointsCanCode|TestWorkspaceChanges — 全部 PASS
  • npm test — 前端 56 个测试全部 PASS

Cache-impact: medium — checkpoint.go 影响所有会话的编辑追踪
Cache-guard: go test ./internal/checkpoint/... + go test ./desktop/ -run TestWorkspaceChanges
image
image

image

@github-actions github-actions Bot added v2 Go rewrite (1.x) — main-v2 branch, active development desktop Wails desktop app (desktop/**) labels Jun 24, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 69ff944046

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread desktop/workspace_changes.go Outdated
Comment on lines +136 to +140
for i := 0; i < 50; i++ {
a.mu.RLock()
ctrl := tab.Ctrl
a.mu.RUnlock()
if ctrl != nil {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Skip controller polling after startup failure

When a tab's async controller build finishes with an error, buildTabControllerWithContext leaves Ctrl nil and records StartupErr/Ready, but this loop still waits the full 5 seconds before returning. Because workspaceBaseForTab also routes Git history/detail requests through this helper, opening or refreshing the Changes panel on a tab with a bad config or failed session build stalls every request even though the git data could be shown immediately; break out when the tab is ready with no controller (or has StartupErr/was removed) instead of polling only for Ctrl.

Useful? React with 👍 / 👎.

Comment thread desktop/workspace_changes.go Outdated
ctrl := tab.Ctrl
a.mu.RUnlock()
if ctrl != nil {
return workspaceRoot, ctrl, true

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Return the workspace root after the build settles

In cases where the async build reconciles a pinned session’s metadata, reconcileTabWithPinnedSessionMeta can update tab.WorkspaceRoot before setting tab.Ctrl, but this path still returns the root captured before waiting. The first Changes refresh after opening/resuming such a session can therefore combine the newly-built controller’s checkpoint paths with an old workspace base, causing paths to be normalized against the wrong directory and hiding or misreporting changes until a later refresh; read tab.WorkspaceRoot under the lock together with the controller you return.

Useful? React with 👍 / 👎.

@ttmouse

ttmouse commented Jun 24, 2026

Copy link
Copy Markdown
Contributor Author

macOS CI 的失败是 flaky test TestExecuteBatchSegmentsAroundWrites,和本 PR 改动无关。

  • 失败原因:混合批处理耗时 434ms(阈值 400ms),仅超 34ms
  • 本地验证:同一测试 300ms 通过
  • 是 CI runner 负载波动导致的偶发超时,重跑应该就能过

@ttmouse

ttmouse commented Jun 24, 2026

Copy link
Copy Markdown
Contributor Author

@codex review。

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 23374fac61

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread desktop/workspace_changes.go Outdated
Comment on lines +137 to +141
for i := 0; i < 50; i++ {
a.mu.RLock()
ctrl := tab.Ctrl
ready := tab.Ready
a.mu.RUnlock()

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Do not block git history on controller build

This wait was added inside workspaceChangesTarget, but the same helper is also used by workspaceBaseForTab for git-only endpoints such as WorkspaceGitHistory and WorkspaceGitCommitDetail. When a tab has a known WorkspaceRoot but tab.Ctrl is still nil/Ready false during a slow async build, opening the Changed panel now leaves git history/detail calls stuck in this 5-second polling loop even though they do not need the controller; the wait should be limited to the checkpoint/session-change path or made optional for callers that only need the workspace base.

Useful? React with 👍 / 👎.

onClick={() => toggleSection("session")}
role="button"
tabIndex={0}
onKeyDown={(e) => { if (e.key === "Enter" || e.key === " ") { e.preventDefault(); toggleSection("session"); } }}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P3 Badge Stop view-toggle keys from collapsing the section

When keyboard focus is on the tree/list toggle button, pressing Enter or Space bubbles to this header onKeyDown, so the section collapses/expands instead of only switching views (the child only stops click propagation). This makes the new view toggle effectively hide the changes for keyboard users; ignore events whose target is the action button or stop propagation on the button's key handler.

Useful? React with 👍 / 👎.

onClick={() => selectFile(change.path)}
>
<FileText size={14} className="workspace-tree__icon" />
<span className="workspace-tree__name" style={{ flex: 1 }}>{basename(change.path)}</span>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P3 Badge Keep parent paths visible in list view

In the default list view, each session change now renders only basename(change.path), so two edited files like src/index.ts and tests/index.ts appear as identical index.ts rows with the same badge. The previous list included the parent path, and without it users can easily open the wrong changed file unless they switch views; include the directory (or otherwise disambiguate duplicate basenames) in the list row.

Useful? React with 👍 / 👎.

问题 esengine#4544: Agent 修改代码后,右下角的「本会话变更」为空

根因修复:
- checkpoint.List() 不再屏蔽当前 turn 的文件路径
- WorkspaceChanges 增加异步 Controller 构建等待 (spin-wait up to 5s)
- 切换对话时 dockRefreshKey 正确 bump

前端优化:
- 新增树状/列表视图切换
- VS Code 风格的单层目录分组
- 视觉统一:无边框、hover 高亮、可折叠分区
- 修复多处 padding/icon/alignment CSS 细节
- 展示 M badge 标记未提交的会话变更

测试:
- checkpoint: go test ./internal/checkpoint/... PASS
- workspace: TestWorkspaceChangesWaitsForAsyncControllerBuild
- 前端: npm test 56 个 PASS

Cache-impact: medium — checkpoint.go 影响所有会话编辑追踪
@ttmouse ttmouse force-pushed the fix/workspace-changes-display branch from 9375e38 to 58fe6d0 Compare June 29, 2026 17:41
ttmouse added 3 commits June 30, 2026 02:05
Blocking:
- i18n: replace hardcoded "No details available" with t("workspace.noDetails")
- a11y: add :focus-within/:focus-visible to hover-revealed icon CSS

Should-fix:
- CSS: unify --workspace-tree-width default 280→300px to match JS constant
- Go: extract waitForTabCtrl polling params as package-level constants
- persistence: persist expandedTreeDirs to localStorage (was only in-memory)
- UI: add FileText icon to Files tab for visual symmetry with Changed tab
- UI: hide breadcrumb when preview header already shows file path (dedup)
- UI: replace ChevronDown rotate(180deg) with explicit ChevronUp icon

Nit:
- perf: memoize gitStatusMap with useMemo instead of rebuilding on every render

Cache-impact: low — CSS defaults, i18n keys, a11y selectors
The squashed commit used WorkspaceChangeView[] in the tree view
grouping code but the type was not imported from ../lib/types.
This caused the CI desktop job's tsc --noEmit step to fail.

Cache-impact: none — types-only import fix
Cache-guard: pnpm --dir frontend build
Duplicate filenames are handled by switching to tree view instead.
Cache-impact: none
@ttmouse ttmouse force-pushed the fix/workspace-changes-display branch from 6deb5d5 to 202bba2 Compare June 30, 2026 15:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

desktop Wails desktop app (desktop/**) v2 Go rewrite (1.x) — main-v2 branch, active development

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant