`DownloadEngine` grows async query methods that wrap plugin iteration: `get_all_downloads` (concatenates every plugin's active downloads), `get_download_status` (first plugin to recognize the id wins), `cancel_download` (with source-hint routing — streaming sources go direct, unknown hints route to Soulseek as peer username), and `clear_all_completed_downloads` (skips unconfigured plugins). Code moved from the orchestrator's hand-iterated loops into the engine. Orchestrator delegation comes in B3 — for B2 the engine methods exist but nothing calls them yet. Per-plugin behavior preserved verbatim (defensive `try ... except` swallows per-iteration, unconfigured-skip on clear, source-hint routing semantics). Phase A pinning tests + 8 new engine query tests catch any drift. Pure additive — zero behavior change for users. |
||
|---|---|---|
| .. | ||
| __init__.py | ||
| engine.py | ||