* feat(#530): add SessionSearch models + searchSessions endpoint + contract tests
* feat(#530): wire server-backed search into Sessions screen (debounce + render)
* style(#530): ktlint import ordering on HermesApiService
* fix(#530): ktlint-clean overlap wrap + map search snippet to title
* fix(#530): map search snippet to title so results show + highlight
* fix(#530): render search hits as honest result cards instead of faking title
Backend SessionSearchResult carries no session name (only snippet + metadata),
so mapping snippet->title made the card show raw excerpt as the title. Instead,
render a dedicated SearchResultCard: 'Match' label + session id, highlighted
snippet as body, and source/model/played-at chips. Added SessionInfo.model and
a friendly relative-time formatter. ktlint clean, compileDebugKotlin + unit
tests pass.
* fix(#530): strip JSON from search snippet + tighten result card padding
* fix(#530): strip FTS highlight markers from search snippet on client
agy's backend change re-wraps matched terms in >>>term<<< markers inside the
clean snippet, but the mobile highlights by raw query term and never consumed
those markers — so literal '>>>'/'<<<' would render in result text. Strip the
markers before passing the snippet to highlightText so the query highlight
still works on clean text.
* fix(#530): integrate tree-flattening hierarchy with search modes in SessionsScreen
* fix(#530): fix test assertion and mock ApiClient in SessionsViewModelTest
* fix(#530): resolve compose PaddingValues compile error and fix slash-preservation test path
* fix(#530): clean search snippet from JSON payload and add unit test
---------
Co-authored-by: M57 <m57@hermes-control.app>