In add_to_queue, check download_history before INSERT OR IGNORE. Without
this check, a fire-and-forget /queue/complete failure on the extension side
would allow the same download_id to be re-inserted after complete_download()
deleted it from the queue — creating phantom queued entries for already-
finished downloads.
- retry_from_history() and retry_all_failed() now DELETE the original
history entry after re-queuing it. Previously the old entry stayed
in history causing exponential growth on repeated retry→cancel→retry
cycles.
- Add deduplicate() called once on singleton creation to clean up
existing duplicate queue/history entries left by the bug:
1. In-status dedup (keep highest id per model+version+status)
2. Cross-status dedup (prefer completed > failed > canceled)
3. Queue dedup (keep highest rowid per model+version)
4. Orphan queue cleanup (source='retry' entries obsoleted by
terminal history entries)