Skip to content

Improve Files and Changes workflow - #52

Merged
powerfooI merged 4 commits into
mainfrom
feat/files-changes-workflow
Aug 26, 2026
Merged

Improve Files and Changes workflow#52
powerfooI merged 4 commits into
mainfrom
feat/files-changes-workflow

Conversation

@powerfooI

Copy link
Copy Markdown
Owner

Summary

  • share Git diff summary state between Files and Changes, with bounded cache lifecycle and post-mutation refreshes
  • align Git status badges and preserve staged/unstaged entries for partially staged files
  • embed per-file changes in the file preview while preserving wrap and split/unified preferences
  • add hunk navigation plus reliable virtualized-line targeting
  • add VS Code-style file-tree keyboard navigation and accessible File/Changes tabs and context menus
  • harden preview and diff request races, invalidation, and resource cleanup

Verification

  • bun test — 699 passed, 1 skipped
  • bun run format:check
  • bun run lint
  • cd web && bun run typecheck
  • cd web && bun run build
  • browser smoke test for file-tree navigation, keyboard context menus, and File/Changes tab navigation

Copilot AI lite review requested due to automatic review settings August 26, 2026 02:12

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

The file explorer’s immediate onActiveDiffEntriesChange emission can publish diff entries in an inconsistent order, causing incorrect default/primary entry selection for embedded per-file changes.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

This PR enhances the workspace “Files” and “Changes” inspector experience in web/src by sharing and reusing Git diff summary state, improving per-file change visibility, and adding richer navigation/accessibility for file trees and diffs.

Changes:

  • Introduces a shared, keyed Git diff summary store with deduping, queuing, and resource retirement, plus unit tests.
  • Unifies git status badge presentation via normalized U/A/M/D/C codes, and preserves multiple entries for partially staged files.
  • Embeds per-file diffs into the file preview, adds diff hunk navigation, and improves keyboard navigation + ARIA roles for the file tree and menus.
File summaries
File Description
web/src/styles.css Adds styling for focused rows, git status code badges, embedded diff view, preview tabs, and hunk navigation UI.
web/src/gitDiffSummaryStore.ts New shared external-store cache for diff summaries with bounded retention and race handling.
web/src/gitDiffSummaryStore.test.ts Tests deduping, queued refresh, retirement behavior for the shared diff summary store.
web/src/gitDiffStatus.ts Adds normalization for git diff entry kinds/statuses into U/A/M/D/C plus human labels.
web/src/gitDiffStatus.test.ts Tests code normalization for mixed explorer/diff-viewer states.
web/src/components/WorkspaceInspectorHost.tsx Wires file explorer to provide active diff entries; adds embedded per-file changes view and keyboard focus handoff.
web/src/components/FilePreviewContent.tsx Adds accessible File/Changes tabs and supports rendering embedded changes content.
web/src/components/FileExplorerDialog.tsx Integrates shared diff summary, adds keyboard tree navigation + context menu roles, improves preview cache invalidation.
web/src/components/FileExplorerDialog.test.ts Adds tests for partial-stage entry preservation and preview invalidation behavior.
web/src/components/DiffViewerPanel.tsx Switches to shared diff summary store, adds working-entry selection helpers, aligns status badges to U/A/M/D/C.
web/src/components/DiffViewerPanel.test.ts Updates/extends directory expansion behavior tests for refreshed trees.
web/src/components/DiffContentView.tsx Adds embedded mode, hunk navigation with virtualized targeting, and inline “Load diff/Retry” actions.
web/src/components/DiffContentView.test.ts Tests hunk target parsing and hunk index navigation behavior.
CHANGELOG.md Documents the user-visible workflow improvements under Unreleased.
Review details
  • Files reviewed: 14/14 changed files
  • Comments generated: 1
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread web/src/components/FileExplorerDialog.tsx
Copilot AI review requested due to automatic review settings August 26, 2026 02:36

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔵 Needs a closer look

The change set spans multiple stateful UI surfaces (shared caching, keyboard navigation, embedded diff rendering) where subtle regressions are hard to rule out via diff-only review.

Review details

Suppressed comments (2)

Previously missed (1) — in code that hasn't changed since the last review.

web/src/components/DiffViewerPanel.tsx:1273

  • statusCodes is derived from a Set, so its iteration order depends on child.entries ordering. Sorting the resulting array makes badge order stable across refreshes and avoids unnecessary DOM churn.
      const statusCodes = Array.from(
        new Set(child.entries.map((entry) => gitDiffCode(entry))),
      );

web/src/components/FileExplorerDialog.tsx:546

  • Directory codes are built from a Set and converted with Array.from(...), which keeps insertion order and can vary based on server entry ordering. Sorting the result avoids non-deterministic badge ordering.
      codes: Array.from(directoryCodes.get(path) ?? []),
  • Files reviewed: 14/14 changed files
  • Comments generated: 1
  • Review effort level: Lite

Comment thread web/src/components/FileExplorerDialog.tsx Outdated
Copilot AI review requested due to automatic review settings August 26, 2026 02:49

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔵 Needs a closer look

DiffViewerPanel can leave summaryRequestLoading stuck true when the diff context changes during an in-flight refresh, disabling the UI until reload.

Review details

Suppressed comments (2)

Previously missed (1) — in code that hasn't changed since the last review.

web/src/components/DiffViewerPanel.tsx:817

  • loadSummary uses summaryRequestLoading to disable/animate refresh controls, but it can get stuck true if the diff scope/workspace context changes while a refresh is in flight (the finally guard prevents clearing it). Track the latest summary refresh with a request sequence/token so only the newest request clears the loading flag, regardless of scope changes.

This issue also appears on line 945 of the same file.

  const pendingWorkingEntriesRef = useRef<GitDiffEntry[]>([]);
  const preferredSummarySelectionRef = useRef<GitDiffEntry | null>(null);
  const diffScopeRef = useRef(diffScope);
  diffScopeRef.current = diffScope;
  const onSelectionChangeRef = useRef(onSelectionChange);

web/src/components/DiffViewerPanel.tsx:949

  • The finally block only clears summaryRequestLoading when isCurrentContext(workspaceId, scope) is still true. If the user switches scope/workspace during an in-flight refresh, this leaves summaryRequestLoading stuck true (and the UI disabled). Use a request sequence/token to ensure only the most recent refresh clears the flag even when context changes.
    const scope = diffScope;
    preferredSummarySelectionRef.current = previousSelected;
    advanceDiffCacheRevision(
      diffCacheKey(connectionClient, workspaceId, scope, cacheResourceKey),
    );
  • Files reviewed: 14/14 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

Copilot AI review requested due to automatic review settings August 26, 2026 05:57

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔵 Needs a closer look

The changes span multiple interdependent UI state/caching paths (shared summary store, embedded diffs, and keyboard navigation) where subtle race/focus regressions are hard to fully validate from diff review alone.

Review details
  • Files reviewed: 14/14 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

@powerfooI
powerfooI merged commit 228656a into main Aug 26, 2026
2 checks passed
@powerfooI
powerfooI deleted the feat/files-changes-workflow branch August 26, 2026 06:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants