What's wrong
SwitchPage(baseRepo) and RefreshPage() call UpdateSimilarRepos(repo) directly and synchronously, on the ImGui render thread, every time the user clicks a different repo in the left panel. UpdateSimilarRepos loops over every other repo in Options.Repos and calls DiffRepos, which for each pair: runs git ls-files -z twice via GitCli.RunIn (blocking subprocess launches), intersects the tracked-file lists, synchronously File.ReadAllTexts every matching file from both working trees, and runs a full DiffPlex line diff on each.
Why it matters (concrete failure scenario)
This is exactly the kind of work the rest of the app deliberately backgrounds — FetchRepo, PullRepo, PushRepo, and the Clone button all wrap their git calls in Task/Task.Run specifically so git subprocess latency doesn't stall rendering. UpdateSimilarRepos has no such wrapper. This tool's stated purpose is managing "dozens of sibling repositories." With, say, 30 cloned repos and a handful of shared files each (editorconfig, workflow files, props files — exactly the files this tool exists to reconcile), clicking a repo in the list spawns ~60 git processes and reads/diffs every shared file before the frame can render, freezing the window (Windows will show "Not Responding" if slow enough) — on every single repo click, not just once at startup.
Suggested fix / acceptance criteria
Move UpdateSimilarRepos onto a background Task, updating repo.SimilarRepoDiffs and calling QueueLog/re-render on completion, consistent with how Fetch/Pull/Push already report their state. Consider caching ListTrackedFiles per repo (it doesn't change until the next fetch/pull) instead of re-running git ls-files for every pairwise comparison. Acceptance: switching the base repo with 20+ cloned repos does not visibly stall input/rendering.
Files: ProjectDirector/ProjectDirector.cs (SwitchPage, RefreshPage, UpdateSimilarRepos, DiffRepos)
What's wrong
SwitchPage(baseRepo)andRefreshPage()callUpdateSimilarRepos(repo)directly and synchronously, on the ImGui render thread, every time the user clicks a different repo in the left panel.UpdateSimilarReposloops over every other repo inOptions.Reposand callsDiffRepos, which for each pair: runsgit ls-files -ztwice viaGitCli.RunIn(blocking subprocess launches), intersects the tracked-file lists, synchronouslyFile.ReadAllTexts every matching file from both working trees, and runs a full DiffPlex line diff on each.Why it matters (concrete failure scenario)
This is exactly the kind of work the rest of the app deliberately backgrounds —
FetchRepo,PullRepo,PushRepo, and the Clone button all wrap their git calls inTask/Task.Runspecifically so git subprocess latency doesn't stall rendering.UpdateSimilarReposhas no such wrapper. This tool's stated purpose is managing "dozens of sibling repositories." With, say, 30 cloned repos and a handful of shared files each (editorconfig, workflow files, props files — exactly the files this tool exists to reconcile), clicking a repo in the list spawns ~60 git processes and reads/diffs every shared file before the frame can render, freezing the window (Windows will show "Not Responding" if slow enough) — on every single repo click, not just once at startup.Suggested fix / acceptance criteria
Move
UpdateSimilarReposonto a backgroundTask, updatingrepo.SimilarRepoDiffsand callingQueueLog/re-render on completion, consistent with how Fetch/Pull/Push already report their state. Consider cachingListTrackedFilesper repo (it doesn't change until the next fetch/pull) instead of re-runninggit ls-filesfor every pairwise comparison. Acceptance: switching the base repo with 20+ cloned repos does not visibly stall input/rendering.Files:
ProjectDirector/ProjectDirector.cs(SwitchPage,RefreshPage,UpdateSimilarRepos,DiffRepos)