### Added
- **HTTPS support for the built-in web client** — the bundled client (port 3774) now uses `https.createServer` when `JEAN2_TLS_ENABLED=true`, reading the same certificate and key files (`JEAN2_TLS_CERT_FILE`, `JEAN2_TLS_KEY_FILE`) as the main server. Previously the client always served plain HTTP regardless of TLS configuration, which caused insecure-context blocks on mobile browsers and broken `wss://` connections when accessing the server remotely (e.g., over Tailscale). The server now passes `JEAN2_SERVER_URL` with the correct protocol prefix (`https://` vs `http://`) so the client SDK derives the right WebSocket protocol (`wss://` vs `ws://`).
- **`jean2 open` CLI command uses HTTPS when TLS is enabled** — the open command now opens `https://localhost:3774` instead of `http://localhost:3774` when `JEAN2_TLS_ENABLED=true`, so the correct protocol is used when launching a browser to the built-in client.

### Changed
- **Client `LaunchResult.url` reflects actual protocol** — the logged URL and returned `LaunchResult` now show `https://` when TLS is enabled, matching what the client child process actually serves.

### Fixed
- **Duplicate model IDs across providers no longer cause 0 models** — model ID uniqueness validation is now per-provider instead of global. You can have `gpt-5.5` under both the `codex` and `openai` providers without validation failures. Previously, the validator rejected the entire `models.json` if any model ID appeared in multiple providers, which silently returned an empty model list.
- **Model sync no longer skips models from new providers** — `syncModels` and `mergeProviderModels` now track model IDs per-provider. Previously, connecting a provider like OpenAI where upstream models shared IDs with existing providers (e.g., Codex) caused those models to be silently skipped during merge.
- **`findModel` / `findModelVariant` accept optional `providerId`** — added an optional second parameter for scoped lookups when model IDs overlap across providers. Backward compatible — when omitted, falls back to global search.
- **`createModel` checks duplicates within the target provider only** — no longer rejects adding a model ID that exists in a different provider.
- **`setDefaults` verifies the default model exists in the specified default provider** — no longer validates against a flat global model list.
- **`deleteProvider` uses a direct provider-aware check** — simplified the default-model guard to check the provider being deleted directly, avoiding ambiguity when the default model ID exists in multiple providers.
