* Chat search: match across all messages, not just title and preview
The Cmd/Ctrl+K chat search only matched the thread title and a 120
character preview of the newest message, so keywords anywhere else in a
conversation were unfindable. Build a per-thread haystack from the title
plus every message's text and match against that.
The haystack is lowercased once at index build time, so the keystroke
filter only normalizes the short query instead of re-lowercasing the
whole conversation per item.
* Chat search: search user messages first, expand to all only if no hit
User messages are short while assistant replies can be very long, so
matching the whole conversation on every keystroke scales with the
assistant text. Store a separate userSearchText (title plus user
messages) and match it first, expanding to the full per thread
searchText only when nothing matches user text anywhere. Row filtering
moves into selectVisibleChats with cmdk shouldFilter disabled so the
tier choice is deterministic.
* Chat search: include tool calls and sources in the full-text tier
extractText now also pulls reasoning/thinking, tool call name/args/result
and cited source title/url, so the expanded full-conversation tier finds
keywords that only appear in tool activity. Drop the now-unused preview
field since search no longer matches on it.
* Chat search: drop base64 image/audio payloads from the index
extractText stringified tool-call results wholesale, so an
image_generation result (image_b64) or audio payload would pour megabytes
of base64 into searchText and get lowercased on every rebuild. Add
searchableText, which keeps readable tool args/results (tool name, prompt,
text) but skips binary keys and strips data URLs, long base64 runs and the
__IMAGES__ suffix.