Anti-corruption boundary tightened on the TMDB adapter:
* TmdbMovieInfo / TmdbShowInfo now carry domain VOs (TmdbId, ImdbId,
MovieTitle, ReleaseYear, ShowStatus) instead of raw scalars —
validation happens at the boundary, not three layers later.
* ShowStatus enum added (domain/tv_shows/value_objects) with a
from_tmdb() mapper that falls back to UNKNOWN + logs a warning on
unrecognized values. TVShow.status is now ShowStatus, not str.
* MovieTitle cap raised from 100 to 150 chars.
* MediaResult / ExternalIds dropped. Replaced by per-media search
DTOs: TmdbMovieSearchResult and TmdbShowSearchResult. Neither
carries imdb_id — search no longer enriches with external_ids
(callers needing imdb_id follow up with get_movie_info /
get_tv_show_info on the chosen tmdb_id).
* TMDBClient: search_multi / search_media / _parse_result removed.
search_movies (/search/movie) and search_shows (/search/tv) added,
each parsing hits into VO-typed DTOs.
* SearchMovieUseCase returns a list of MovieHit (flattened to
primitives for the agent). New symmetric SearchShowUseCase +
ShowHit / SearchShowResponse DTOs.
* agent/tools/api.py: find_media_imdb_id → search_movies +
search_shows wrappers.
* FileEntry moved from domain/shared/ports/filesystem_scanner.py to
domain/shared/file_entry.py (it's a DTO, not a Protocol); size_kb
(float) → size (int bytes). Scanner and SubtitleIdentifier
updated.
Tests: 79/79 pass on tests/infrastructure/api/ +
tests/application/test_search_movie.py +
tests/application/test_search_show.py.