The header now reads as a header: subtle fill, bottom divider, muted
semibold labels via a shared ColumnHeaderButtonStyle instead of four
copies of inline styling. Each sortable column gains a funnel button
opening a filter flyout — substring boxes for Name and Branch, radio
choices for Status (kept in lockstep with the toolbar chips both ways)
and Archived (all/only/not). Active filters tint their funnel accent and
carry the state in the automation name.
Filtering logic lives in WorkspaceViewModel (NameFilter/BranchFilter/
ArchivedFilter compose by AND with the status filter; selection is
untouched, so hidden rows still sync) with five new headless tests.
Verified live against a real 269-repo load: filtering to a non-match
empties the table and shows the empty-filter hint.
Name filtering also addresses the review's P1 "no repository name
search" finding at its first level (#30).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
SyncRequest is a positional record, so its generated ToString printed the
token — and the type ships publicly on NuGet. ToString now redacts it
(regression test added).
UpdateService constructed GithubSource with prerelease:false while every
release shipped so far is a GitHub prerelease, so no installed build could
ever discover an update. Prerelease installs (semver with a '-suffix') now
look at prerelease releases; stable installs keep excluding them.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The toolbar used Auto|Auto|*|Auto columns, so nothing could shrink: with
~40px of slack at the default window size, any width pressure (narrower
window, Windows text scaling, localization, longer count labels) pushed
the Sync/Cancel group past the right edge — measured via UIA at 820px
width, both buttons were laid out entirely outside the visible region.
The action groups now drop to their own right-aligned row whenever the
measured widths do not fit on one row (UpdateToolbarLayout +
ToolbarSingleRow/TwoRow visual states). Measuring instead of a
window-width trigger covers text scaling and localization, not just
window size. The selection summary trims, and the run progress bar
narrows from 160 to 120px.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Per-repo failure isolation is exception-based, and several of those
exceptions surface from native libgit2 frames; with Just My Code enabled
Visual Studio breaks on each as user-unhandled, pausing every thread. A
measured probe (269-repo live sync, WM_NULL round-trips) shows the message
pump never exceeds 70ms outside the debugger.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>