"""Process-wide configuration loaded from environment (`.env`). Everything that varies between deployments (creds, paths, ports) lives here. User-facing agent/MCP/frontend definitions live in ``/config/config.py`` and are loaded by ``config_loader`` (Phase 0.3). """ from __future__ import annotations from pathlib import Path from pydantic_settings import BaseSettings, SettingsConfigDict class Settings(BaseSettings): """Runtime environment for the gateway process.""" model_config = SettingsConfigDict( env_file=".env", env_file_encoding="utf-8", extra="ignore" ) database_url: str admin_user: str admin_pass: str session_secret: str internal_mcp_port: int = 8765 config_path: Path = Path("/config/config.py") claude_runner_user: str | None = None """Unix user the claude subprocess runs as. Needs the gateway to be root.""" claude_home: Path | None = None """``HOME`` for the claude subprocess (its ``~/.claude`` lives there).""" raycast_bearer: str | None = None raycast_config_path: Path = Path("/config/raycast.json") raycast_device_id: str | None = None """64-hex-char stable per-install id. Required when any ``RaycastAgent`` is configured — generate once via ``secrets.token_hex(32)`` and keep in ``.env`` so Raycast doesn't see every restart as a new device.""" raycast_locale: str = "en-US" """``Accept-Language`` header sent by the shared ``raycast_api.Client`` and the default locale used to render auto ``UserPreferences``. One value per gateway since we open one Client total.""" bootstrap_tokens: str = "" """Out-of-band token seed: ``name1:value1,name2:value2``. Empty is fine — DB-issued tokens (admin UI) carry steady-state auth. This env channel layers alongside the DB store and is kept for first-run setup, disaster recovery (admin password lost), and ``examples/`` smoke tests. Bootstrap tokens implicitly carry scope ``"*"`` and never get a ``last_used_at`` stamp (no DB row). """