Files
clide/clide-web/clide_web/config.py
T
jpmschweitzerandClaude Opus 4.6 56a8ea4ba4 feat: add clide-web package replacing ttyd + zellij
Python web server that wraps Clide for browser access. Replaces the
previous ttyd (C binary) + zellij (Rust binary) stack with a single
FastAPI application using tmux for session persistence.

Key features:
- WebSocket ↔ PTY bridge via tmux attach
- Project switching via /projects/<name> URL routing
- Vendored xterm.js for offline LAN operation
- Auto-respawn on Clide exit (tmux pane-died hook)
- Setup wizard for first-run configuration
- No scrollbar (TUI manages its own scrolling)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 17:03:43 +01:00

109 lines
2.9 KiB
Python

"""Configuration for clide-web using Pydantic Settings + DB preferences."""
from __future__ import annotations
import logging
from pathlib import Path
from pydantic_settings import BaseSettings, SettingsConfigDict
logger = logging.getLogger(__name__)
DB_PATH = Path.home() / ".clide" / "clide.db"
class ClideWebSettings(BaseSettings):
"""Web server settings.
Priority: env vars > .env file > DB preferences > defaults.
"""
model_config = SettingsConfigDict(
env_prefix="CLIDE_WEB_",
env_file=".env",
env_file_encoding="utf-8",
extra="ignore",
)
# Server
host: str = "0.0.0.0"
port: int = 8888
# Paths
projects_dir: Path = Path("/mnt/media/Projects")
clide_bin: str = "clide"
# Database
db_path: Path = DB_PATH
# Sessions
session_timeout_seconds: int = 3600
session_cleanup_interval_seconds: int = 60
# Terminal
default_cols: int = 120
default_rows: int = 40
term: str = "xterm-256color"
# UI
font_family: str = "JetBrains Mono, monospace"
font_size: int = 14
default_theme: str = "summer-night"
def load_settings() -> ClideWebSettings:
"""Load settings, overlaying DB preferences onto defaults.
Env vars still take highest priority (Pydantic handles that).
DB preferences override hardcoded defaults for fields not set via env.
"""
import os
# First load from env/defaults
settings = ClideWebSettings()
# Then overlay DB preferences for fields not explicitly set via env
try:
prefs = _load_db_preferences(settings.db_path)
except Exception:
logger.debug("Could not load DB preferences (DB may not exist yet)")
return settings
env_prefix = "CLIDE_WEB_"
field_map = {
"projects_dir": ("projects_dir", Path),
"clide_bin": ("clide_bin", str),
"port": ("port", int),
"font_size": ("font_size", int),
"default_theme": ("default_theme", str),
"font_family": ("font_family", str),
"host": ("host", str),
}
for pref_key, (field_name, field_type) in field_map.items():
env_var = f"{env_prefix}{field_name.upper()}"
# Only apply DB pref if env var is NOT set
if env_var not in os.environ and pref_key in prefs:
try:
setattr(settings, field_name, field_type(prefs[pref_key]))
except (ValueError, TypeError):
pass
return settings
def _load_db_preferences(db_path: Path) -> dict[str, str]:
"""Read UserPreference records from the database."""
if not db_path.exists():
return {}
from clide.models.db import UserPreference
from clide.services.database import get_engine
from sqlmodel import Session as DBSession
from sqlmodel import select
engine = get_engine(db_path)
with DBSession(engine) as db:
stmt = select(UserPreference)
return {p.key: p.value for p in db.exec(stmt).all()}