Skip to content

feat(desktop): file-changes tree view in dual-solve panes#294

Open
dripsmvcp wants to merge 8 commits into
vouchdev:testfrom
dripsmvcp:feat/dual-solve-file-changes-view
Open

feat(desktop): file-changes tree view in dual-solve panes#294
dripsmvcp wants to merge 8 commits into
vouchdev:testfrom
dripsmvcp:feat/dual-solve-file-changes-view

Conversation

@dripsmvcp

@dripsmvcp dripsmvcp commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

dual-solve file-changes view

each dual-solve candidate pane showed a flat list of changed filenames followed by a single column that stacked every changed file's hunks. once a diff touches more than a file or two that's hard to scan and there's no way to focus one file.

this replaces that block with a reusable file-changes view modeled on the gittensor-ui repositories components (fileTree.ts + RepositoryCodeBrowser), trimmed to changed files only: a compact nested file tree (folders-first) as a narrow rail drives a content pane that shows just the selected file's diff. selection is local per candidate, so the claude and codex panes navigate independently.

what's in here:

  • fileTree.ts — pure buildFileTree(paths) returning a nested FileNode[], folders-first alphabetical, with intermediate directories synthesized from path segments. unit-tested.
  • diffParse.ts — lifts parseDiff out of Diff.tsx so the existing renderer and the new view share one parser (behavior unchanged).
  • FileChanges.tsx — the tree rail + per-file diff pane, derived entirely from the candidate's existing diff string.
  • DualSolve.tsx — swaps the ul + Diff block for <FileChanges>.

renderer-only: no new ipc, no server or transport change. the candidate diff already arrives from the job poll; the tree is derived from it.

verification: tsc -b clean; 100 passed (100) including 7 new buildFileTree cases. also checked live in the electron app — the rail renders the nested tree per candidate, defaults to the first file, and clicking a file swaps the diff pane (src/parser.pytests/test_parser.py).

out of scope by design: go-to-file search, breadcrumbs, directory-listing tables, commit metadata, synced selection across candidates, syntax highlighting.

Summary by CodeRabbit

  • New Features
    • Added a split file-changes view with a navigable file tree (rail) and dedicated diff pane, with improved row styling and hover/selection states.
  • Bug Fixes
    • Preserved the selected file across diff refreshes when possible, with graceful fallback.
    • Added clearer empty states when no file changes or diff content are available.
  • Tests
    • Added coverage for file tree building (nesting, sorting, de-duplication) and unified diff parsing (multi-file, headers, empty input).

plind-junior and others added 6 commits June 26, 2026 00:47
chore: promote test branch to main (desktop app + examples)
each dual-solve candidate pane showed a flat filename list plus a single
column that stacked every changed file's hunks, which is hard to scan once
a diff touches more than one or two files.

replace that block with a reusable FileChanges view modeled on the
gittensor-ui repositories components: a compact nested file tree
(folders-first) as a narrow rail drives a content pane showing only the
selected file's diff. selection is local per candidate, so the claude and
codex panes navigate independently.

- fileTree.ts: pure buildFileTree(paths) -> nested FileNode[], folders-first
  alphabetical, intermediate dirs synthesized from path segments; unit-tested.
- diffParse.ts: lift parseDiff out of Diff.tsx so the renderer and the new
  view share one parser (behavior unchanged).
- FileChanges.tsx: tree rail + per-file diff pane, derived entirely from the
  candidate's existing diff string. no new ipc or server change.
- DualSolve.tsx: swap the ul + Diff block for <FileChanges>.

renderer-only. typecheck clean; 100 tests pass including 7 new tree cases.
@github-actions github-actions Bot added the size: M 200-499 changed non-doc lines label Jun 30, 2026
shows the per-candidate file tree rail driving the diff pane.
@coderabbitai

coderabbitai Bot commented Jun 30, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 4ec63fff-3d21-4353-9a72-a90416a0d5c8

📥 Commits

Reviewing files that changed from the base of the PR and between ed9678a and e1883ce.

⛔ Files ignored due to path filters (1)
  • desktop/docs/screenshots/dual-solve-file-changes.png is excluded by !**/*.png
📒 Files selected for processing (4)
  • desktop/src/renderer/src/app.css
  • desktop/src/renderer/src/components/FileChanges.tsx
  • desktop/src/renderer/src/components/diffParse.ts
  • desktop/test/diff-parse.test.ts
✅ Files skipped from review due to trivial changes (2)
  • desktop/test/diff-parse.test.ts
  • desktop/src/renderer/src/app.css
🚧 Files skipped from review as they are similar to previous changes (2)
  • desktop/src/renderer/src/components/diffParse.ts
  • desktop/src/renderer/src/components/FileChanges.tsx

📝 Walkthrough

Walkthrough

Diff parsing is extracted into a shared module, a nested file-tree builder and tests are added, and a new FileChanges view renders a left file rail with a right-side diff pane. DualSolve now uses FileChanges for candidate diffs.

Changes

FileChanges dual-pane diff navigator

Layer / File(s) Summary
diffParse module and Diff.tsx refactor
desktop/src/renderer/src/components/diffParse.ts, desktop/src/renderer/src/components/Diff.tsx, desktop/test/diff-parse.test.ts
Defines DiffLine/DiffFile and parseDiff in a shared module; Diff.tsx imports the parser and keeps the same diff rendering flow; tests cover file splitting, headers, content markers, and empty input.
fileTree module and tests
desktop/src/renderer/src/components/fileTree.ts, desktop/test/file-tree.test.ts
Adds FileNode, sortNodes, and buildFileTree for nested path trees, with tests for directory synthesis, ordering, deduplication, and deep nesting.
FileChanges component and CSS
desktop/src/renderer/src/components/FileChanges.tsx, desktop/src/renderer/src/app.css
Implements FileChanges with recursive rail rendering, diff selection state, empty-state handling, and the dual-pane layout styles for the file-changes view.
DualSolve wiring
desktop/src/renderer/src/views/DualSolve.tsx
Replaces the Diff import with FileChanges and renders FileChanges for the candidate ok branch while keeping the error branch separate.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related issues

Poem

A bunny hops through paths so neat,
With folders first and diffs toీట్?
One pane left, one pane right,
Changed files dance in tidy light.
🐇✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise and accurately summarizes the main change: adding a file-changes tree view in Dual-Solve panes.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 Stylelint (17.14.0)
desktop/src/renderer/src/app.css

Error: ENOENT: no such file or directory, open '/.stylelintrc.json'
at async open (node:internal/fs/promises:640:25)
at async Object.readFile (node:internal/fs/promises:1287:14)
at async #readConfiguration (/usr/local/lib/node_modules/stylelint/node_modules/cosmiconfig/dist/Explorer.js:83:26)
at async load (/usr/local/lib/node_modules/stylelint/node_modules/cosmiconfig/dist/Explorer.js:20:48)
at async Explorer.load (/usr/local/lib/node_modules/stylelint/node_modules/cosmiconfig/dist/Explorer.js:23:20)
at async getConfigForFile (file:///usr/local/lib/node_modules/stylelint/lib/getConfigForFile.mjs:72:5)
at async resolveOptionValue (file:///usr/local/lib/node_modules/stylelint/lib/utils/resolveOptionValue.mjs:27:24)
at async standalone (file:///usr/local/lib/node_modules/stylelint/lib/standalone.mjs:127:22)


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai

coderabbitai Bot commented Jun 30, 2026

Copy link
Copy Markdown

Caution

Review failed

An error occurred during the review process. Please try again later.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai 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.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@desktop/src/renderer/src/components/diffParse.ts`:
- Around line 26-31: The diff parsing in diffParse is over-matching file header
markers, causing real added/removed lines like `++counter` or `--flag` to be
dropped. Update the skip logic in the parser branch that checks
`line.startsWith(...)` so it only ignores actual patch headers (`+++ ` and `---
`) while preserving content lines that merely begin with `++` or `--`. Keep the
change localized to the diff line filtering logic so both diff views render
those lines correctly.

In `@desktop/src/renderer/src/components/FileChanges.tsx`:
- Around line 48-57: The file row in TreeRow is currently rendered as a
clickable div, which makes it mouse-only and not keyboard-focusable. Update the
TreeRow render in FileChanges to use a real button element with type="button"
while keeping the existing selection and onClick behavior tied to node.path.
Also add the corresponding focused-state styling in
desktop/src/renderer/src/app.css so the selected row has a clear keyboard focus
indicator matching the existing fc-file / fc-file sel styling.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: fc38eaac-aa2e-47d3-8aa3-ee65105532c4

📥 Commits

Reviewing files that changed from the base of the PR and between 94e84b1 and ed9678a.

⛔ Files ignored due to path filters (1)
  • desktop/docs/screenshots/dual-solve-file-changes.png is excluded by !**/*.png
📒 Files selected for processing (7)
  • desktop/src/renderer/src/app.css
  • desktop/src/renderer/src/components/Diff.tsx
  • desktop/src/renderer/src/components/FileChanges.tsx
  • desktop/src/renderer/src/components/diffParse.ts
  • desktop/src/renderer/src/components/fileTree.ts
  • desktop/src/renderer/src/views/DualSolve.tsx
  • desktop/test/file-tree.test.ts

Comment thread desktop/src/renderer/src/components/diffParse.ts
Comment thread desktop/src/renderer/src/components/FileChanges.tsx Outdated
two coderabbit findings on vouchdev#294:

- diffParse dropped any content line starting with "+++"/"---", so a real
  added "++counter" or removed "--flag" line vanished from the diff. restrict
  the header skip to the actual markers "+++ " / "--- " (trailing space + path).
  adds diff-parse.test.ts covering the regression and basic parsing.
- file rows in the tree rail were clickable <div>s — mouse-only, not
  keyboard-focusable. switch to <button type="button"> and add a focus-visible
  style; the .fc-file class now resets button chrome so the look is unchanged.

verified live: rows are real buttons, keyboard-focusable, selection still swaps
the diff pane. typecheck clean; 104 tests pass.
@dripsmvcp dripsmvcp changed the base branch from main to test June 30, 2026 07:19
@github-actions github-actions Bot added docs documentation, specs, examples, and repo guidance ci github actions and automation tests tests and fixtures size: XL 1000 or more changed non-doc lines and removed size: M 200-499 changed non-doc lines labels Jun 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci github actions and automation docs documentation, specs, examples, and repo guidance size: XL 1000 or more changed non-doc lines tests tests and fixtures

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants