feat(search): live automatic-search activity indicator (sidebar)#723
Draft
kevinheneveld wants to merge 1 commit into
Draft
feat(search): live automatic-search activity indicator (sidebar)#723kevinheneveld wants to merge 1 commit into
kevinheneveld wants to merge 1 commit into
Conversation
The background sweep now reports per-book activity to the UI so you can
see what it's doing without tailing logs. A compact pill above the
sidebar version footer shows the current line ("Searching N indexers
for X", pulsing while active; "Search idle" otherwise).
Built on the existing SearchProgress realtime channel (includeAutomatic
opt-in already present): the automatic-search sweep and the indexer
search workflow emit searching/grabbed/no_results/idle via a new
SearchProgressReporter.BroadcastAutomaticAsync; a process-local
SearchActivityTracker keeps the current event plus the last 30 outcomes
so a fresh page hydrates from GET /search/activity immediately instead
of waiting for the next SignalR event — which during an idle window
could be hours away. Interactive Add-New search is unaffected.
The tracker's rolling outcome feed is exposed by the endpoint and kept
in the frontend store for a future activity panel; the sidebar pill
renders the current line.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
A live activity indicator for the automatic-search sweep: a sidebar pill that shows what the background search is doing right now ("Searching 4 indexers for …", "Grabbed 2 release(s) for …", "Search idle — last sweep processed 31 book(s)"), driven over the existing search-progress SignalR channel.
SearchActivityTracker(singleton): holds the current stage + a rolling 30-entry feed of recent per-book outcomes; hydrated on page load via a newGET /search/activityendpoint (in aSearchController.Activity.cspartial, keeping the main controller under the 500-line architecture cap).SearchProgressReporter.BroadcastAutomaticAsync: broadcaststype: "automatic"progress events through the existingIHubBroadcasterplumbing and records them in the tracker.IndexerSearchWorkflow(gated onisAutomaticSearch), per-book outcome + idle transitions in the automatic-search sweep.searchActivityPinia store (SignalR + hydration) and aSidebarSearchActivitypill.Note: the kevin/live original also had a dashboard "recent outcomes" panel; canary has no dashboard view, so this PR ships the sidebar half. The endpoint and store already carry the 30-outcome feed, so a future panel (e.g. on the Activity view) can consume it with zero backend changes.
Why
The automatic-search sweep is invisible today — you can't tell whether it's running, stuck, or idle without reading logs. This surfaces it where you already are.
Tests
7 new backend tests (tracker state/feed + reporter automatic-broadcast) and a 3-case vitest spec for the store. Full suite passing;
vue-tsc+ eslint + prettier clean.🤖 Generated with Claude Code