cavectl: SMTP via mailpit (default) or external server

cave-keycloak's realm import hardcoded SMTP to host "mailpit" port
1025 — which only worked on the laptop because cave-prod has a
cave-prod-mailpit sidecar. On a fresh VPS the lookup failed, email
verification mails went nowhere, and registration users got stuck.

Realm:
- All seven SMTP fields are now placeholders (__SMTP_HOST__ etc.).
- Adds user and password fields so authenticated relays work.

cave-keycloak entrypoint:
- Substitutes the new SMTP_* placeholders from env, with the old
  laptop defaults (mailpit:1025, no auth) preserved as fallbacks
  so existing laptop deploys keep working.

cavectl:
- New SMTPConfig (mode: "mailpit" or "external", host, port, user,
  password, from, from_display_name, starttls, ssl). Default is
  mailpit so out-of-the-box deploys still capture mail somewhere.
- PortsConfig gains Mailpit (default 9025); cavectl init picks a
  free one and Default() sets it.
- New MailpitEnabled() helper; plan adds a CreateContainer step
  for mailpit before keycloak so DNS resolves at SMTP-send time.
- New createMailpit() in apply; createKeycloak now threads
  SMTP_HOST/PORT/FROM/USER/PASSWORD/SSL/STARTTLS/AUTH env vars
  to the keycloak container. In mailpit mode host/port are
  overridden to the local mailpit container.

To switch a deploy to real outbound mail, set in cave.yaml:

  smtp:
      mode: external
      host: smtp.example.com
      port: 587
      starttls: true
      user: ...
      password: ...
      from: cave@example.com
      from_display_name: Cave

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Anthony Green2026-05-24 14:09:26 -0400 87862f82b9a3efd7b65764c90785f99cca81e839
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>