Closes#35
## Summary
- Wraps `handler.merge(...)` in `await asyncio.to_thread(...)` so the CPU-bound YAML parse/merge/dump runs in the thread pool instead of blocking the event loop
- Change is at the generic `handle()` dispatch site — applies to all current and future `_VirtualHandler` implementations without modification
- Also fixes a pre-existing bug in `examples/single-file/remotes.yaml` where `base_url` and `package` keys were merged onto a single line, preventing `docker-compose up` from starting the app
## Measured performance gain
19-member `helm-all` virtual repo, single uvicorn worker, cache miss (38s merge):
| | Concurrent `/health` latency |
|---|---|
| Before (blocking) | **37,721ms** for first request (stalled) |
| After (thread pool) | **8–63ms** for all requests |
## Test plan
- [x] 278 unit tests pass (`make test`)
- [x] Live concurrency test: cache miss merge started in background, 5 concurrent `/health` checks measured — all <65ms
- [x] Baseline comparison: same test with blocking call — first health check stalled 37.7s
Reviewed-on: #38
Repository types now live under dedicated top-level keys instead of a
shared remotes: block distinguished by a type field:
remotes: caching proxy remotes (no type field needed)
virtuals: virtual merged-index repositories
locals: local upload repositories
Routes for local repos move from /api/v1/remote/ to /api/v1/local/.
config.py gains get_virtual_config() and get_local_config() lookups.
Root endpoint now reports all three sections. Drop root conf.d/ (was
an exact duplicate of examples/conf.d-method/).
Reviewed-on: #31
Adds a new virtual repo type that merges indexes from multiple member remotes
of the same package type. Currently supports helm (index.yaml merge with URL
rewriting). Member fetches run in parallel; merged index is Redis-cached at
min(mutable_ttl) across members.
Reviewed-on: #30
examples/single-file/remotes.yaml — original monolithic config
examples/conf.d-method/ — one yaml per remote (alpine, github, pypi)
docker-compose updated to mount from examples/single-file/.