Skip to content

fix(search): preserve semantic results and pagination#396

Merged
sozercan merged 2 commits into
mainfrom
fix-search
Jul 20, 2026
Merged

fix(search): preserve semantic results and pagination#396
sozercan merged 2 commits into
mainfrom
fix-search

Conversation

@sozercan

Copy link
Copy Markdown
Owner

Summary

  • Preserve YouTube Music's server-ranked search order with semantic result cases for songs, videos, albums, audiobooks, artists, profiles, playlists, podcast shows, and episodes.
  • Parse current search containers, watch-based top results, localized metadata, playlist aliases, and legacy plus action-envelope continuations.
  • Add Videos, Profiles, and Episodes filters with caller-owned, generation-safe pagination that stays valid across query, filter, and account changes.
  • Keep existing rows visible while loading additional pages and provide localized labels and context-menu/navigation behavior for the new result families.
  • Extend API Explorer with a bounded search audit, add sanitized fixtures, update discovery documentation and ADR-0028, and expand configurable UI-test mock coverage.

Root cause

Search parsing assumed older shelf-only response shapes, rebuilt results from separate type buckets, and treated most playable rows as songs. This dropped modern item-section and watch-based results, discarded server ranking, and coupled pagination to a shared mutable client cursor.

Validation

  • swift build
  • swiftlint --strict — 0 violations
  • Focused search, parser, client, view-model, localization, and mock suites — 166 tests passed
  • Parser/model continuation follow-ups — 97 tests passed
  • Previously timing-sensitive suites rerun in isolation — 112 tests passed
  • Localization catalog JSON and every .strings file validated
  • Live guest API audit across representative queries reported zero unhandled result rows/cards
  • Structured Codex autoreview — clean, no accepted/actionable findings

UI tests were not run.

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>
Copilot AI review requested due to automatic review settings July 20, 2026 01:51

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Modernizes YouTube Music search to preserve server ordering, semantic result types, and generation-safe pagination.

Changes:

  • Adds ordered parsing for nine semantic result families and modern continuation shapes.
  • Adds Videos, Profiles, and Episodes filters with updated UI actions.
  • Expands localization, fixtures, API Explorer auditing, tests, and architecture documentation.
Show a summary per file
File Description
Sources/APIExplorer/SearchAudit.swift Adds bounded search-shape auditing.
Sources/APIExplorer/main.swift Exposes search audit and continuation options.
Sources/Kaset/Models/MusicVideoType.swift Adds official-source search video semantics.
Sources/Kaset/Models/Podcast.swift Centralizes episode-to-song conversion.
Sources/Kaset/Models/SearchResponse.swift Introduces ordered semantic search results.
Sources/Kaset/Resources/Localizable.xcstrings Adds translated search labels.
Sources/Kaset/Resources/ar.lproj/Localizable.strings Adds Arabic labels.
Sources/Kaset/Resources/de.lproj/Localizable.strings Adds German labels.
Sources/Kaset/Resources/en.lproj/Localizable.strings Adds English labels.
Sources/Kaset/Resources/es.lproj/Localizable.strings Adds Spanish labels.
Sources/Kaset/Resources/fr.lproj/Localizable.strings Adds French labels.
Sources/Kaset/Resources/id.lproj/Localizable.strings Adds Indonesian labels.
Sources/Kaset/Resources/it.lproj/Localizable.strings Adds Italian labels.
Sources/Kaset/Resources/ko.lproj/Localizable.strings Adds Korean labels.
Sources/Kaset/Resources/nl.lproj/Localizable.strings Adds Dutch labels.
Sources/Kaset/Resources/pl.lproj/Localizable.strings Adds Polish labels.
Sources/Kaset/Resources/pt.lproj/Localizable.strings Adds Portuguese labels.
Sources/Kaset/Resources/ru.lproj/Localizable.strings Adds Russian labels.
Sources/Kaset/Resources/sv.lproj/Localizable.strings Adds Swedish labels.
Sources/Kaset/Resources/tr.lproj/Localizable.strings Adds Turkish labels.
Sources/Kaset/Resources/uk.lproj/Localizable.strings Adds Ukrainian labels.
Sources/Kaset/Services/API/MockUITestYTMusicClient+DefaultData.swift Expands default semantic search data.
Sources/Kaset/Services/API/MockUITestYTMusicClient+SearchFixtures.swift Parses configurable UI-test results.
Sources/Kaset/Services/API/MockUITestYTMusicClient.swift Implements new search endpoints.
Sources/Kaset/Services/API/Parsers/ParsingHelpers.swift Improves metadata filtering.
Sources/Kaset/Services/API/Parsers/SearchResponseParser+Support.swift Adds metadata and continuation helpers.
Sources/Kaset/Services/API/Parsers/SearchResponseParser.swift Parses ordered modern search containers.
Sources/Kaset/Services/API/YTMusicClient.swift Adds filtered endpoints and explicit pagination.
Sources/Kaset/Services/Protocols.swift Updates the search client contract.
Sources/Kaset/ViewModels/SearchViewModel.swift Adds filters and safe pagination ownership.
Sources/Kaset/Views/MainWindow.swift Clears search on account changes.
Sources/Kaset/Views/PodcastsView.swift Reuses episode playback conversion.
Sources/Kaset/Views/SearchView.swift Renders and handles new result families.
Sources/Kaset/Views/SharedViews/FavoritesContextMenu.swift Handles semantic result cases.
Sources/Kaset/Views/SharedViews/ShareContextMenu.swift Adds sharing for new result cases.
Tests/KasetTests/Fixtures/search_direct_item_section.json Covers direct item sections.
Tests/KasetTests/Fixtures/search_later_flex_columns.json Covers later metadata columns.
Tests/KasetTests/Fixtures/search_music_shelf_continuation.json Covers shelf continuations.
Tests/KasetTests/Fixtures/search_playlist_watch_endpoints.json Covers playlist watch destinations.
Tests/KasetTests/Fixtures/search_tabbed_mixed.json Covers mixed semantic ranking.
Tests/KasetTests/Fixtures/search_top_result_watch_endpoints.json Covers playable top results.
Tests/KasetTests/GuestModeAPIClientTests.swift Verifies public filtered search.
Tests/KasetTests/Helpers/MockYTMusicClient.swift Updates mock endpoints and pagination.
Tests/KasetTests/MockUITestYTMusicClientSearchTests.swift Tests configurable semantic fixtures.
Tests/KasetTests/ParsingHelpersTests.swift Tests metadata exclusions.
Tests/KasetTests/SearchResponseParserTestFixtures.swift Provides parser fixture builders.
Tests/KasetTests/SearchResponseParserTests.swift Tests modern parser behavior.
Tests/KasetTests/SearchResponseTests.swift Tests semantic projections and identity.
Tests/KasetTests/SearchViewModelTests.swift Tests filters and stale pagination.
Tests/KasetTests/SwiftTestingHelpers/TestStringConvertible.swift Formats new result cases in failures.
Tests/KasetTests/YTMusicClientTests.swift Tests routing and continuation reset.
docs/adr/0028-ordered-semantic-music-search-results.md Documents the search architecture.
docs/adr/README.md Registers ADR-0028.
docs/api-discovery.md Documents current search API shapes.

Review details

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

  • Files reviewed: 54/54 changed files
  • Comments generated: 4
  • Review effort level: Medium

Comment thread Sources/Kaset/Services/API/Parsers/SearchResponseParser+Support.swift Outdated
Comment thread Sources/Kaset/Services/API/Parsers/SearchResponseParser+Support.swift Outdated
Comment thread Tests/KasetTests/Helpers/MockYTMusicClient.swift
Signed-off-by: Sertac Ozercan <sozercan@gmail.com>
Copilot AI review requested due to automatic review settings July 20, 2026 03:13

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

  • Files reviewed: 54/54 changed files
  • Comments generated: 0 new
  • Review effort level: Medium

@sozercan
sozercan merged commit 9a42bf6 into main Jul 20, 2026
10 checks passed
@sozercan
sozercan deleted the fix-search branch July 20, 2026 03:50
Yoddikko pushed a commit to Yoddikko/kasetPlus that referenced this pull request Jul 21, 2026
Signed-off-by: Sertac Ozercan <sozercan@gmail.com>
Yoddikko added a commit to Yoddikko/kasetPlus that referenced this pull request Jul 21, 2026
…ozercan#392/sozercan#391/sozercan#389/sozercan#368 skipped)

Move sozercan#396 and sozercan#379 to "Already synced"; add sozercan#392, sozercan#391, sozercan#389 and sozercan#368 to
"Deliberately skipped" — all four conflict in the PlayerService/queue/AI
area that diverged from skipping sozercan#374, and are unportable without it (or,
for sozercan#389, gate on the broken test target).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants